Android实现CoverFlow效果
2012-07-30 20:59
866 查看
先上一张效果图:
上代码,看了代码什么都明白
CoverFlow从Gallery继承过来
viewsource
print?
这个就是CoverFlow类,说明几点:
1.成员函数
mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
其他的变量都可以无视
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的getter和setter函数都可以无视
ImageAdapter适配器:
viewsource
print?
BitmapDrawabledrawable=(BitmapDrawable)i.getDrawable();
drawable.setAntiAlias(true);
是保证图片绕Y旋转了以后不会出现锯齿.
下面是Activity:
viewsource
print?
参考自:http://www.eoeandroid.com/thread-70209-1-1.htmlhttp://www.apkbus.com/android-18441-1-1.html
上代码,看了代码什么都明白
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 CameramCamera= 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(Contextcontext){ |
022 | super (context); |
023 | this .setStaticTransformationsEnabled( true ); |
024 | } |
025 |
026 | public CoverFlow(Contextcontext,AttributeSetattrs){ |
027 | super (context,attrs); |
028 | this .setStaticTransformationsEnabled( true ); |
029 | } |
030 |
031 | public CoverFlow(Contextcontext,AttributeSetattrs, 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(Viewview){ |
074 | return view.getLeft()+view.getWidth()/ 2 ; |
075 | } |
076 |
077 | protected boolean getChildStaticTransformation(Viewchild,Transformationt){ |
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 | *@paramw |
100 | *Currentwidthofthisview. |
101 | *@paramh |
102 | *Currentheightofthisview. |
103 | *@paramoldw |
104 | *Oldwidthofthisview. |
105 | *@paramoldh |
106 | *Oldheightofthisview. |
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 | *@paramimageView |
117 | *ImageViewtheImageViewwhosebitmapwewanttorotate |
118 | *@paramt |
119 | *transformation |
120 | *@paramrotationAngle |
121 | *theAnglebywhichtorotatetheBitmap |
122 | */ |
123 | private void transformImageBitmap(ImageViewchild,Transformationt, |
124 | int rotationAngle){ |
125 | mCamera.save(); |
126 | final MatriximageMatrix=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 | } |
1.成员函数
mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
其他的变量都可以无视
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的getter和setter函数都可以无视
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 ContextmContext; |
025 | private Integer[]mImageIds={ |
026 | R.drawable.a1, |
027 | R.drawable.a2, |
028 | R.drawable.a3, |
029 | R.drawable.a4, |
030 | R.drawable.a5}; |
031 |
032 | public ImageAdapter(Contextc){ |
033 | mContext=c; |
034 | } |
035 |
036 | public int getCount(){ |
037 | return mImageIds.length; |
038 | } |
039 |
040 | public ObjectgetItem( int position){ |
041 | return position; |
042 | } |
043 |
044 | public long getItemId( int position){ |
045 | return position; |
046 | } |
047 |
048 | public ViewgetView( int position,ViewconvertView,ViewGroupparent){ |
049 |
050 | ImageViewi=createReflectedImages(mContext,mImageIds[position]); |
051 |
052 | i.setLayoutParams( new CoverFlow.LayoutParams( 120 , 100 )); |
053 | i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); |
054 |
055 | //设置的抗锯齿 |
056 | BitmapDrawabledrawable=(BitmapDrawable)i.getDrawable(); |
057 | drawable.setAntiAlias( true ); |
058 | return i; |
059 | } |
060 |
061 | public float getScale( boolean focused, int offset){ |
062 | return Math.max( 0 , 1 .0f/( float )Math.pow( 2 ,Math.abs(offset))); |
063 | } |
064 |
065 | public ImageViewcreateReflectedImages(ContextmContext, int imageId){ |
066 |
067 | BitmaporiginalImage=BitmapFactory.decodeResource(mContext.getResources(),imageId); |
068 |
069 | final int reflectionGap= 4 ; |
070 |
071 | int width=originalImage.getWidth(); |
072 | int height=originalImage.getHeight(); |
073 |
074 | Matrixmatrix= new Matrix(); |
075 | matrix.preScale( 1 ,- 1 ); |
076 |
077 | BitmapreflectionImage=Bitmap.createBitmap(originalImage, 0 , |
078 | height/ 2 ,width,height/ 2 ,matrix, false ); |
079 |
080 | BitmapbitmapWithReflection=Bitmap.createBitmap(width, |
081 | (height+height/ 2 ),Config.ARGB_8888); |
082 |
083 | Canvascanvas= new Canvas(bitmapWithReflection); |
084 |
085 | canvas.drawBitmap(originalImage, 0 , 0 , null ); |
086 |
087 | PaintdeafaultPaint= new Paint(); |
088 | canvas.drawRect( 0 ,height,width,height+reflectionGap,deafaultPaint); |
089 |
090 | canvas.drawBitmap(reflectionImage, 0 ,height+reflectionGap, null ); |
091 |
092 | Paintpaint= new Paint(); |
093 | LinearGradientshader= new LinearGradient( 0 ,originalImage |
094 | .getHeight(), 0 ,bitmapWithReflection.getHeight() |
095 | +reflectionGap, 0x70ffffff , 0x00ffffff ,TileMode.MIRROR); |
096 |
097 | paint.setShader(shader); |
098 |
099 | paint.setXfermode( new PorterDuffXfermode(Mode.DST_IN)); |
100 |
101 | canvas.drawRect( 0 ,height,width,bitmapWithReflection.getHeight() |
102 | +reflectionGap,paint); |
103 |
104 | ImageViewimageView= new ImageView(mContext); |
105 | imageView.setImageBitmap(bitmapWithReflection); |
106 |
107 | return imageView; |
108 | } |
109 |
110 | } |
drawable.setAntiAlias(true);
是保证图片绕Y旋转了以后不会出现锯齿.
下面是Activity:
01 | package com.coverflow; |
02 |
03 | import android.app.Activity; |
04 | import android.graphics.Color; |
05 | import android.os.Bundle; |
06 |
07 | import com.gallery.R; |
08 |
09 | public class HelloAndroid extends Activity{ |
10 | /**Calledwhentheactivityisfirstcreated.*/ |
11 | @Override |
12 | public void onCreate(BundlesavedInstanceState){ |
13 | super .onCreate(savedInstanceState); |
14 |
15 | CoverFlowcf= new CoverFlow( this ); |
16 | //cf.setBackgroundResource(R.drawable.shape); |
17 | cf.setBackgroundColor(Color.BLACK); |
18 | cf.setAdapter( new ImageAdapter( this )); |
19 | ImageAdapterimageAdapter= new ImageAdapter( this ); |
20 | cf.setAdapter(imageAdapter); |
21 | //cf.setAlphaMode(false); |
22 | //cf.setCircleMode(false); |
23 | cf.setSelection( 2 , true ); |
24 | cf.setAnimationDuration( 1000 ); |
25 | setContentView(cf); |
26 | } |
27 |
28 | } |
相关文章推荐
- Android实现CoverFlow效果
- Android 通过伪3D变换可以基本实现coverflow的效果
- Android自定义Gallery,实现CoverFlow效果
- Android实现CoverFlow效果三
- Android 通过伪3D变换可以基本实现coverflow的效果
- Android实现CoverFlow效果 一
- Android实现CoverFlow效果控件的实例代码
- Android中类似于IOS的CoverFlow效果实现源码分析
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android Gallery实现苹果的coverflow效果
- Android实现CoverFlow效果二
- 如何在Android中实现全屏,去掉标题栏效果
- Android实现粒子雨效果
- Android实现通用的ActivityGroup(效果类似Android微博客户端主界面),强烈建议不要再使用TabActivity
- 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(二)——大图显示模式、评论“盖楼”效果实现详解
- Android自定义View实现HTML图文环绕效果