自定义控件-----CoverFlow

CoverFlow--我也不知道为什么要叫这个名字,貌似是从iphone上继承过来的?

随便了,反正就是这个样子了

自定义控件-----CoverFlow



此控件的设计和实现思路和部分代码同样是剽窃某网站上的,因为时间太久了,找不到原文地址了..杯具,所以我才来做备份的.

此类是从Gallery继承过来的,用法自然也就和Gallery一样了

程序的背景是一个xml陪的渐变背景,具体可以参看另外一篇"渐变背景"的文章

图片的倒影效果是适用了ReflectionImage控件,具体可以参看上一篇博文.

先看代码吧,看了代码什么都明白了

view plaincopy to clipboardprint?
package com.myview; 
import android.content.Context; 
import android.graphics.Camera; 
import android.graphics.Matrix; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.animation.Transformation; 
import android.widget.Gallery; 
import android.widget.ImageView; 
public class CoverFlow extends Gallery { 
     
    private Camera mCamera = new Camera(); 
    private int mMaxRotationAngle = 50; 
    private int mMaxZoom = -380; 
    private int mCoveflowCenter; 
    private boolean mAlphaMode = true; 
    private boolean mCircleMode = false; 
    public CoverFlow(Context context) { 
        super(context); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public CoverFlow(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public CoverFlow(Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public int getMaxRotationAngle() { 
        return mMaxRotationAngle; 
    } 
    public void setMaxRotationAngle(int maxRotationAngle) { 
        mMaxRotationAngle = maxRotationAngle; 
    } 
    public boolean getCircleMode() { 
        return mCircleMode; 
    } 
    public void setCircleMode(boolean isCircle) { 
        mCircleMode = isCircle; 
    } 
    public boolean getAlphaMode() { 
        return mAlphaMode; 
    } 
    public void setAlphaMode(boolean isAlpha) { 
        mAlphaMode = isAlpha; 
    } 
    public int getMaxZoom() { 
        return mMaxZoom; 
    } 
    public void setMaxZoom(int maxZoom) { 
        mMaxZoom = maxZoom; 
    } 
    private int getCenterOfCoverflow() { 
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 
                + getPaddingLeft(); 
    } 
    private static int getCenterOfView(View view) { 
        return view.getLeft() + view.getWidth() / 2; 
    } 
    protected boolean getChildStaticTransformation(View child, Transformation t) { 
        final int childCenter = getCenterOfView(child); 
        final int childWidth = child.getWidth(); 
        int rotationAngle = 0; 
        t.clear(); 
        t.setTransformationType(Transformation.TYPE_MATRIX); 
        if (childCenter == mCoveflowCenter) { 
            transformImageBitmap((ImageView) child, t, 0); 
        } else { 
            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); 
            if (Math.abs(rotationAngle) > mMaxRotationAngle) { 
                rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle 
                        : mMaxRotationAngle; 
            } 
            transformImageBitmap((ImageView) child, t, rotationAngle); 
        } 
        return true; 
    } 
    /**
     * This is called during layout when the size of this view has changed. If
     * you were just added to the view hierarchy, you're called with the old
     * values of 0.
     * 
     * @param w
     *            Current width of this view.
     * @param h
     *            Current height of this view.
     * @param oldw
     *            Old width of this view.
     * @param oldh
     *            Old height of this view.
     */ 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
        mCoveflowCenter = getCenterOfCoverflow(); 
        super.onSizeChanged(w, h, oldw, oldh); 
    } 
    /**
     * Transform the Image Bitmap by the Angle passed
     * 
     * @param imageView
     *            ImageView the ImageView whose bitmap we want to rotate
     * @param t
     *            transformation
     * @param rotationAngle
     *            the Angle by which to rotate the Bitmap
     */ 
    private void transformImageBitmap(ImageView child, Transformation t, 
            int rotationAngle) { 
        mCamera.save(); 
        final Matrix imageMatrix = t.getMatrix(); 
        final int imageHeight = child.getLayoutParams().height; 
        final int imageWidth = child.getLayoutParams().width; 
        final int rotation = Math.abs(rotationAngle); 
        mCamera.translate(0.0f, 0.0f, 100.0f); 
        // As the angle of the view gets less, zoom in 
        if (rotation <= mMaxRotationAngle) { 
            float zoomAmount = (float) (mMaxZoom + (rotation * 1.5)); 
            mCamera.translate(0.0f, 0.0f, zoomAmount); 
            if (mCircleMode) { 
                if (rotation < 40) 
                    mCamera.translate(0.0f, 155, 0.0f); 
                else 
                    mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f); 
            } 
            if (mAlphaMode) { 
                ((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5)); 
            } 
        } 
        mCamera.rotateY(rotationAngle); 
        mCamera.getMatrix(imageMatrix); 
        imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2)); 
        imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2)); 
        mCamera.restore(); 
    } 



这个就是CoverFlow类,说明几点

1. 成员函数

    mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等

    mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度

    mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.

    其他的变量都可以无视

2. 构造函数里面的setStaticTransformationsEnabled



protected void setStaticTransformationsEnabled (boolean enabled)
When this property is set to true, this ViewGroup supports static transformations on children; this causes getChildStaticTransformation(View, android.view.animation.Transformation) to be invoked when a child is drawn. Any subclass overriding getChildStaticTransformation(View, android.view.animation.Transformation) should set this property to true.

Parameters
enabled True to enable static transformations on children, false otherwise.
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了

其他的getter和setter函数都可以无视

view plaincopy to clipboardprint?
package com.hello; 
import com.hello.R; 
import com.myview.*; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.drawable.BitmapDrawable; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
public class HelloAndroid extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
         
        CoverFlow cf = new CoverFlow(this);  
        cf.setBackgroundResource(R.drawable.shape); 
        cf.setAdapter(new ImageAdapter(this));  
        ImageAdapter imageAdapter = new ImageAdapter(this); 
        cf.setAdapter(imageAdapter); 
//      cf.setAlphaMode(false);  
//      cf.setCircleMode(false); 
//      cf.setSelection(3, true);   
        cf.setAnimationDuration(1000); 
        setContentView(cf); 
    } 
     
     
     
    public class ImageAdapter extends BaseAdapter { 
        int mGalleryItemBackground; 
        private Context mContext; 
        private Integer[] mImageIds = {  
                R.drawable.a,  
                R.drawable.b, 
                R.drawable.d, 
                R.drawable.e, 
                R.drawable.c}; 
         
        public ImageAdapter(Context c) { 
            mContext = c; 
        } 
        public int getCount() { 
            return mImageIds.length; 
        } 
        public Object getItem(int position) { 
            return position;  
        } 
        public long getItemId(int position) { 
            return position; 
        } 
        public View getView(int position, View convertView, ViewGroup parent) { 
            ReflectionImage i = new ReflectionImage(mContext); 
             
            i.setImageResource(mImageIds[position]); 
            i.setLayoutParams(new CoverFlow.LayoutParams(96, 76)); 
            i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 
            // Make sure we set anti-aliasing otherwise we get jaggies 
            BitmapDrawable drawable = (BitmapDrawable) i.getDrawable(); 
            drawable.setAntiAlias(true); 
            return i; 
        } 
  
        public float getScale(boolean focused, int offset) { 
            return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset))); 
        } 
    } 



BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();

drawable.setAntiAlias(true);

是保证图片绕Y旋转了以后不会出现锯齿

你可能感兴趣的:(C++,c,android,OS,C#)