自定义控件-----CoverFlow

来源:互联网 发布:淘宝详情页ps怎么设计 编辑:程序博客网 时间:2024/04/30 11:44
 

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

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

 

 

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

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

 

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

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

 

 

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

[java] view plaincopyprint?
  1. package com.myview;  
  2. import android.content.Context;  
  3. import android.graphics.Camera;  
  4. import android.graphics.Matrix;  
  5. import android.util.AttributeSet;  
  6. import android.view.View;  
  7. import android.view.animation.Transformation;  
  8. import android.widget.Gallery;  
  9. import android.widget.ImageView;  
  10. public class CoverFlow extends Gallery {  
  11.       
  12.     private Camera mCamera = new Camera();  
  13.     private int mMaxRotationAngle = 50;  
  14.     private int mMaxZoom = -380;  
  15.     private int mCoveflowCenter;  
  16.     private boolean mAlphaMode = true;  
  17.     private boolean mCircleMode = false;  
  18.     public CoverFlow(Context context) {  
  19.         super(context);  
  20.         this.setStaticTransformationsEnabled(true);  
  21.     }  
  22.     public CoverFlow(Context context, AttributeSet attrs) {  
  23.         super(context, attrs);  
  24.         this.setStaticTransformationsEnabled(true);  
  25.     }  
  26.     public CoverFlow(Context context, AttributeSet attrs, int defStyle) {  
  27.         super(context, attrs, defStyle);  
  28.         this.setStaticTransformationsEnabled(true);  
  29.     }  
  30.     public int getMaxRotationAngle() {  
  31.         return mMaxRotationAngle;  
  32.     }  
  33.     public void setMaxRotationAngle(int maxRotationAngle) {  
  34.         mMaxRotationAngle = maxRotationAngle;  
  35.     }  
  36.     public boolean getCircleMode() {  
  37.         return mCircleMode;  
  38.     }  
  39.     public void setCircleMode(boolean isCircle) {  
  40.         mCircleMode = isCircle;  
  41.     }  
  42.     public boolean getAlphaMode() {  
  43.         return mAlphaMode;  
  44.     }  
  45.     public void setAlphaMode(boolean isAlpha) {  
  46.         mAlphaMode = isAlpha;  
  47.     }  
  48.     public int getMaxZoom() {  
  49.         return mMaxZoom;  
  50.     }  
  51.     public void setMaxZoom(int maxZoom) {  
  52.         mMaxZoom = maxZoom;  
  53.     }  
  54.     private int getCenterOfCoverflow() {  
  55.         return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2  
  56.                 + getPaddingLeft();  
  57.     }  
  58.     private static int getCenterOfView(View view) {  
  59.         return view.getLeft() + view.getWidth() / 2;  
  60.     }  
  61.     protected boolean getChildStaticTransformation(View child, Transformation t) {  
  62.         final int childCenter = getCenterOfView(child);  
  63.         final int childWidth = child.getWidth();  
  64.         int rotationAngle = 0;  
  65.         t.clear();  
  66.         t.setTransformationType(Transformation.TYPE_MATRIX);  
  67.         if (childCenter == mCoveflowCenter) {  
  68.             transformImageBitmap((ImageView) child, t, 0);  
  69.         } else {  
  70.             rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);  
  71.             if (Math.abs(rotationAngle) > mMaxRotationAngle) {  
  72.                 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle  
  73.                         : mMaxRotationAngle;  
  74.             }  
  75.             transformImageBitmap((ImageView) child, t, rotationAngle);  
  76.         }  
  77.         return true;  
  78.     }  
  79.     /** 
  80.      * This is called during layout when the size of this view has changed. If 
  81.      * you were just added to the view hierarchy, you're called with the old 
  82.      * values of 0. 
  83.      *  
  84.      * @param w 
  85.      *            Current width of this view. 
  86.      * @param h 
  87.      *            Current height of this view. 
  88.      * @param oldw 
  89.      *            Old width of this view. 
  90.      * @param oldh 
  91.      *            Old height of this view. 
  92.      */  
  93.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  94.         mCoveflowCenter = getCenterOfCoverflow();  
  95.         super.onSizeChanged(w, h, oldw, oldh);  
  96.     }  
  97.     /** 
  98.      * Transform the Image Bitmap by the Angle passed 
  99.      *  
  100.      * @param imageView 
  101.      *            ImageView the ImageView whose bitmap we want to rotate 
  102.      * @param t 
  103.      *            transformation 
  104.      * @param rotationAngle 
  105.      *            the Angle by which to rotate the Bitmap 
  106.      */  
  107.     private void transformImageBitmap(ImageView child, Transformation t,  
  108.             int rotationAngle) {  
  109.         mCamera.save();  
  110.         final Matrix imageMatrix = t.getMatrix();  
  111.         final int imageHeight = child.getLayoutParams().height;  
  112.         final int imageWidth = child.getLayoutParams().width;  
  113.         final int rotation = Math.abs(rotationAngle);  
  114.         mCamera.translate(0.0f, 0.0f, 100.0f);  
  115.         // As the angle of the view gets less, zoom in  
  116.         if (rotation <= mMaxRotationAngle) {  
  117.             float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));  
  118.             mCamera.translate(0.0f, 0.0f, zoomAmount);  
  119.             if (mCircleMode) {  
  120.                 if (rotation < 40)  
  121.                     mCamera.translate(0.0f, 1550.0f);  
  122.                 else  
  123.                     mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);  
  124.             }  
  125.             if (mAlphaMode) {  
  126.                 ((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5));  
  127.             }  
  128.         }  
  129.         mCamera.rotateY(rotationAngle);  
  130.         mCamera.getMatrix(imageMatrix);  
  131.         imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));  
  132.         imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));  
  133.         mCamera.restore();  
  134.     }  
  135. }  


 

这个就是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
enabledTrue to enable static transformations on children, false otherwise.

 

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

 

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

 

 

 

[java] view plaincopyprint?
  1. package com.hello;  
  2. import com.hello.R;  
  3. import com.myview.*;  
  4. import android.app.Activity;  
  5. import android.content.Context;  
  6. import android.graphics.drawable.BitmapDrawable;  
  7. import android.os.Bundle;  
  8. import android.view.View;  
  9. import android.view.ViewGroup;  
  10. import android.widget.BaseAdapter;  
  11. import android.widget.ImageView;  
  12. public class HelloAndroid extends Activity {  
  13.     /** Called when the activity is first created. */  
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.           
  18.         CoverFlow cf = new CoverFlow(this);   
  19.         cf.setBackgroundResource(R.drawable.shape);  
  20.         cf.setAdapter(new ImageAdapter(this));   
  21.         ImageAdapter imageAdapter = new ImageAdapter(this);  
  22.         cf.setAdapter(imageAdapter);  
  23. //      cf.setAlphaMode(false);   
  24. //      cf.setCircleMode(false);  
  25. //      cf.setSelection(3, true);    
  26.         cf.setAnimationDuration(1000);  
  27.         setContentView(cf);  
  28.     }  
  29.       
  30.       
  31.       
  32.     public class ImageAdapter extends BaseAdapter {  
  33.         int mGalleryItemBackground;  
  34.         private Context mContext;  
  35.         private Integer[] mImageIds = {   
  36.                 R.drawable.a,   
  37.                 R.drawable.b,  
  38.                 R.drawable.d,  
  39.                 R.drawable.e,  
  40.                 R.drawable.c};  
  41.           
  42.         public ImageAdapter(Context c) {  
  43.             mContext = c;  
  44.         }  
  45.         public int getCount() {  
  46.             return mImageIds.length;  
  47.         }  
  48.         public Object getItem(int position) {  
  49.             return position;   
  50.         }  
  51.         public long getItemId(int position) {  
  52.             return position;  
  53.         }  
  54.         public View getView(int position, View convertView, ViewGroup parent) {  
  55.             ReflectionImage i = new ReflectionImage(mContext);  
  56.               
  57.             i.setImageResource(mImageIds[position]);  
  58.             i.setLayoutParams(new CoverFlow.LayoutParams(9676));  
  59.             i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);  
  60.             // Make sure we set anti-aliasing otherwise we get jaggies  
  61.             BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();  
  62.             drawable.setAntiAlias(true);  
  63.             return i;  
  64.         }  
  65.    
  66.         public float getScale(boolean focused, int offset) {  
  67.             return Math.max(01.0f / (float) Math.pow(2, Math.abs(offset)));  
  68.         }  
  69.     }  
  70. }  


 

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

drawable.setAntiAlias(true);

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