Android实现CoverFlow效果

先上一张效果图: 


CoverFlow从Gallery继承过来

001 package com.coverflow;
002  
003 import android.content.Context;
004 import android.graphics.Camera;
005 import android.graphics.Matrix;
006 import android.util.AttributeSet;
007 import android.view.View;
008 import android.view.animation.Transformation;
009 import android.widget.Gallery;
010 import android.widget.ImageView;
011  
012 public class CoverFlow extends Gallery {
013  
014     private Camera mCamera = new Camera();
015     private int mMaxRotationAngle = 50;
016     private int mMaxZoom = -380;
017     private int mCoveflowCenter;
018     private boolean mAlphaMode = true;
019     private boolean mCircleMode = false;
020  
021     public CoverFlow(Context context) {
022         super(context);
023         this.setStaticTransformationsEnabled(true);
024     }
025  
026     public CoverFlow(Context context, AttributeSet attrs) {
027         super(context, attrs);
028         this.setStaticTransformationsEnabled(true);
029     }
030  
031     public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
032         super(context, attrs, defStyle);
033         this.setStaticTransformationsEnabled(true);
034     }
035  
036     public int getMaxRotationAngle() {
037         return mMaxRotationAngle;
038     }
039  
040     public void setMaxRotationAngle(int maxRotationAngle) {
041         mMaxRotationAngle = maxRotationAngle;
042     }
043  
044     public boolean getCircleMode() {
045         return mCircleMode;
046     }
047  
048     public void setCircleMode(boolean isCircle) {
049         mCircleMode = isCircle;
050     }
051  
052     public boolean getAlphaMode() {
053         return mAlphaMode;
054     }
055  
056     public void setAlphaMode(boolean isAlpha) {
057         mAlphaMode = isAlpha;
058     }
059  
060     public int getMaxZoom() {
061         return mMaxZoom;
062     }
063  
064     public void setMaxZoom(int maxZoom) {
065         mMaxZoom = maxZoom;
066     }
067  
068     private int getCenterOfCoverflow() {
069         return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
070                 + getPaddingLeft();
071     }
072  
073     private static int getCenterOfView(View view) {
074         return view.getLeft() + view.getWidth() / 2;
075     }
076  
077     protected boolean getChildStaticTransformation(View child, Transformation t) {
078         final int childCenter = getCenterOfView(child);
079         final int childWidth = child.getWidth();
080         int rotationAngle = 0;
081         t.clear();
082         t.setTransformationType(Transformation.TYPE_MATRIX);
083         if (childCenter == mCoveflowCenter) {
084             transformImageBitmap((ImageView) child, t, 0);
085         else {
086             rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
087             if (Math.abs(rotationAngle) > mMaxRotationAngle) {
088                 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
089                         : mMaxRotationAngle;
090             }
091             transformImageBitmap((ImageView) child, t, rotationAngle);
092         }
093         return true;
094     }
095  
096     /**
097      * 这就是所谓的在大小的布局时,这一观点已经发生了改变。如果 你只是添加到视图层次,有人叫你旧的观念 价值观为0。
098      *
099      * @param w
100      *            Current width of this view.
101      * @param h
102      *            Current height of this view.
103      * @param oldw
104      *            Old width of this view.
105      * @param oldh
106      *            Old height of this view.
107      */
108     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
109         mCoveflowCenter = getCenterOfCoverflow();
110         super.onSizeChanged(w, h, oldw, oldh);
111     }
112  
113     /**
114      * 把图像位图的角度通过
115      *
116      * @param imageView
117      *            ImageView the ImageView whose bitmap we want to rotate
118      * @param t
119      *            transformation
120      * @param rotationAngle
121      *            the Angle by which to rotate the Bitmap
122      */
123     private void transformImageBitmap(ImageView child, Transformation t,
124             int rotationAngle) {
125         mCamera.save();
126         final Matrix imageMatrix = t.getMatrix();
127         final int imageHeight = child.getLayoutParams().height;
128         final int imageWidth = child.getLayoutParams().width;
129         final int rotation = Math.abs(rotationAngle);
130         mCamera.translate(0.0f, 0.0f, 100.0f);
131  
132         // 如视图的角度更少,放大
133         if (rotation <= mMaxRotationAngle) {
134             float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
135             mCamera.translate(0.0f, 0.0f, zoomAmount);
136             if (mCircleMode) {
137                 if (rotation < 40)
138                     mCamera.translate(0.0f, 1550.0f);
139                 else
140                     mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);
141             }
142             if (mAlphaMode) {
143                 ((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5));
144             }
145         }
146         mCamera.rotateY(rotationAngle);
147         mCamera.getMatrix(imageMatrix);
148         imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
149         imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
150         mCamera.restore();
151     }
152 }

这个就是CoverFlow类,说明几点:
1. 成员函数
mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
其他的变量都可以无视
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的gettersetter函数都可以无视

ImageAdapter适配器:

001 package com.coverflow;
002  
003 import android.content.Context;
004 import android.graphics.Bitmap;
005 import android.graphics.BitmapFactory;
006 import android.graphics.Canvas;
007 import android.graphics.LinearGradient;
008 import android.graphics.Matrix;
009 import android.graphics.Paint;
010 import android.graphics.PorterDuffXfermode;
011 import android.graphics.Bitmap.Config;
012 import android.graphics.PorterDuff.Mode;
013 import android.graphics.Shader.TileMode;
014 import android.graphics.drawable.BitmapDrawable;
015 import android.view.View;
016 import android.view.ViewGroup;
017 import android.widget.BaseAdapter;
018 import android.widget.ImageView;
019  
020 import com.gallery.R;
021  
022 public class ImageAdapter extends BaseAdapter {
023     int mGalleryItemBackground;
024     private 

更多相关文章

  1. android ndk native_activity.h
  2. android休眠与唤醒驱动流程分析
  3. android 竖屏拍照旋转90度
  4. USB UMS MTP设置过程 (二) UsbDeviceManager.java
  5. Android(安卓)Camera调用流程
  6. Android遥控器定制改变焦点
  7. android 启动流程
  8. Android系统启动流程(四)Launcher启动过程与系统启动流程
  9. Android嵌入式底层开发技术(应试)

随机推荐

  1. 通过自定义View,创建一个圆形指示器
  2. Fragment的API学习笔记
  3. Android的分辨率
  4. android初体验――HelloWord
  5. Android(安卓)Json的使用(1) 使用jsonschem
  6. Android中Activity之间的数据传递(Intent
  7. Android如何找到正确的ALSA底层kcontrol
  8. 给 Android(安卓)开发者的 Flutter 指南
  9. 阿拉伯语系处理方法
  10. delphi xe5 android iny绿色版+最新SDK/N