Android实现CoverFlow效果二
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, 155, 0.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这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的getter和setter函数都可以无视
更多相关文章
- [Android]android studio预览视图时报错
- android之检查service运行状态函数
- Android自定义视图
- Android Studio 基础 之 一键快速实现一个类的 构造函数、getter
- Android实用视图动画及工具系列之四:多状态CheckBox,可设置大小尺
- Android Studio如何提示函数用法
- Android Studio怎样提示函数使用方法
- Android 自定义视图
- Android NDK编程实现终端功能(调用system函数)