生活随笔
收集整理的這篇文章主要介紹了
Android实现CoverFlow效果
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
先上一張效果圖:
上代碼,看了代碼什么都明白
CoverFlow從Gallery繼承過來
view source print?
| 001 | package com.coverflow; |
| 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; |
| 012 | public class CoverFlow extends Gallery { |
| 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; |
| 021 | ????public CoverFlow(Context context) { |
| 022 | ????????super(context); |
| 023 | ????????this.setStaticTransformationsEnabled(true); |
| 026 | ????public CoverFlow(Context context, AttributeSet attrs) { |
| 027 | ????????super(context, attrs); |
| 028 | ????????this.setStaticTransformationsEnabled(true); |
| 031 | ????public CoverFlow(Context context, AttributeSet attrs, int defStyle) { |
| 032 | ????????super(context, attrs, defStyle); |
| 033 | ????????this.setStaticTransformationsEnabled(true); |
| 036 | ????public int getMaxRotationAngle() { |
| 037 | ????????return mMaxRotationAngle; |
| 040 | ????public void setMaxRotationAngle(int maxRotationAngle) { |
| 041 | ????????mMaxRotationAngle = maxRotationAngle; |
| 044 | ????public boolean getCircleMode() { |
| 045 | ????????return mCircleMode; |
| 048 | ????public void setCircleMode(boolean isCircle) { |
| 049 | ????????mCircleMode = isCircle; |
| 052 | ????public boolean getAlphaMode() { |
| 053 | ????????return mAlphaMode; |
| 056 | ????public void setAlphaMode(boolean isAlpha) { |
| 057 | ????????mAlphaMode = isAlpha; |
| 060 | ????public int getMaxZoom() { |
| 061 | ????????return mMaxZoom; |
| 064 | ????public void setMaxZoom(int maxZoom) { |
| 065 | ????????mMaxZoom = maxZoom; |
| 068 | ????private int getCenterOfCoverflow() { |
| 069 | ????????return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 |
| 070 | ????????????????+ getPaddingLeft(); |
| 073 | ????private static int getCenterOfView(View view) { |
| 074 | ????????return view.getLeft() + view.getWidth() / 2; |
| 077 | ????protected boolean getChildStaticTransformation(View child, Transformation t) { |
| 078 | ????????final int childCenter = getCenterOfView(child); |
| 079 | ????????final int childWidth = child.getWidth(); |
| 080 | ????????int rotationAngle = 0; |
| 082 | ????????t.setTransformationType(Transformation.TYPE_MATRIX); |
| 083 | ????????if (childCenter == mCoveflowCenter) { |
| 084 | ????????????transformImageBitmap((ImageView) child, t, 0); |
| 086 | ????????????rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); |
| 087 | ????????????if (Math.abs(rotationAngle) > mMaxRotationAngle) { |
| 088 | ????????????????rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle |
| 089 | ????????????????????????: mMaxRotationAngle; |
| 091 | ????????????transformImageBitmap((ImageView) child, t, rotationAngle); |
| 097 | ?????* 這就是所謂的在大小的布局時(shí),這一觀點(diǎn)已經(jīng)發(fā)生了改變。如果 你只是添加到視圖層次,有人叫你舊的觀念 價(jià)值觀為0。 |
| 100 | ?????*??????????? Current width of this view. |
| 102 | ?????*??????????? Current height of this view. |
| 104 | ?????*??????????? Old width of this view. |
| 106 | ?????*??????????? Old height of this view. |
| 108 | ????protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
| 109 | ????????mCoveflowCenter = getCenterOfCoverflow(); |
| 110 | ????????super.onSizeChanged(w, h, oldw, oldh); |
| 116 | ?????* @param imageView |
| 117 | ?????*??????????? ImageView the ImageView whose bitmap we want to rotate |
| 119 | ?????*??????????? transformation |
| 120 | ?????* @param rotationAngle |
| 121 | ?????*??????????? the Angle by which to rotate the Bitmap |
| 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); |
| 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); |
| 140 | ????????????????????mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f); |
| 142 | ????????????if (mAlphaMode) { |
| 143 | ????????????????((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5)); |
| 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(); |
這個(gè)就是CoverFlow類,說明幾點(diǎn):
1. 成員函數(shù)
mCamera是用來做類3D效果處理,比如z軸方向上的平移,繞y軸的旋轉(zhuǎn)等
mMaxRotationAngle是圖片繞y軸最大旋轉(zhuǎn)角度,也就是屏幕最邊上那兩張圖片的旋轉(zhuǎn)角度
mMaxZoom是圖片在z軸平移的距離,視覺上看起來就是放大縮小的效果.
其他的變量都可以無視
也就是說把這個(gè)屬性設(shè)成true的時(shí)候每次viewGroup(看Gallery的源碼就可以看到它是從ViewGroup間接繼承過來的)在重新畫它的child的時(shí)候都會(huì)促發(fā)getChildStaticTransformation這個(gè)函數(shù),所以我們只需要在這個(gè)函數(shù)里面去加上旋轉(zhuǎn)和放大的操作就可以了
其他的getter和setter函數(shù)都可以無視
ImageAdapter適配器:
view source print?
| 001 | package com.coverflow; |
| 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; |
| 022 | public class ImageAdapter extends BaseAdapter { |
| 023 | ????int mGalleryItemBackground; |
| 024 | ????private Context mContext; |
| 025 | ????private Integer[] mImageIds = {? |
| 026 | ????????????R.drawable.a1, |
| 027 | ????????????R.drawable.a2,? |
| 028 | ????????????R.drawable.a3, |
| 029 | ????????????R.drawable.a4,? |
| 030 | ????????????R.drawable.a5 }; |
| 032 | ????public ImageAdapter(Context c) { |
| 036 | ????public int getCount() { |
| 037 | ????????return mImageIds.length; |
| 040 | ????public Object getItem(int position) { |
| 041 | ????????return position; |
| 044 | ????public long getItemId(int position) { |
| 045 | ????????return position; |
| 048 | ????public View getView(int position, View convertView, ViewGroup parent) { |
| 050 | ????????ImageView i = createReflectedImages(mContext,mImageIds[position]); |
| 052 | ????????i.setLayoutParams(new CoverFlow.LayoutParams(120, 100)); |
| 053 | ????????i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); |
| 055 | ????????// 設(shè)置的抗鋸齒 |
| 056 | ????????BitmapDrawable drawable = (BitmapDrawable) i.getDrawable(); |
| 057 | ????????drawable.setAntiAlias(true); |
| 061 | ????public float getScale(boolean focused, int offset) { |
| 062 | ????????return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset))); |
| 065 | ????public ImageView createReflectedImages(Context mContext,int imageId) { |
| 067 | ????????Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId); |
| 069 | ????????final int reflectionGap = 4; |
| 071 | ????????int width = originalImage.getWidth(); |
| 072 | ????????int height = originalImage.getHeight(); |
| 074 | ????????Matrix matrix = new Matrix(); |
| 075 | ????????matrix.preScale(1, -1); |
| 077 | ????????Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, |
| 078 | ????????????????height / 2, width, height / 2, matrix, false); |
| 080 | ????????Bitmap bitmapWithReflection = Bitmap.createBitmap(width, |
| 081 | ????????????????(height + height / 2), Config.ARGB_8888); |
| 083 | ????????Canvas canvas = new Canvas(bitmapWithReflection); |
| 085 | ????????canvas.drawBitmap(originalImage, 0, 0, null); |
| 087 | ????????Paint deafaultPaint = new Paint(); |
| 088 | ????????canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint); |
| 090 | ????????canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); |
| 092 | ????????Paint paint = new Paint(); |
| 093 | ????????LinearGradient shader = new LinearGradient(0, originalImage |
| 094 | ????????????????.getHeight(), 0, bitmapWithReflection.getHeight() |
| 095 | ????????????????+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.MIRROR); |
| 097 | ????????paint.setShader(shader); |
| 099 | ????????paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); |
| 101 | ????????canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() |
| 102 | ????????????????+ reflectionGap, paint); |
| 104 | ????????ImageView imageView = new ImageView(mContext); |
| 105 | ????????imageView.setImageBitmap(bitmapWithReflection); |
| 107 | ????????return imageView; |
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
是保證圖片繞Y旋轉(zhuǎn)了以后不會(huì)出現(xiàn)鋸齒.
下面是Activity:
view source print?
| 03 | import android.app.Activity; |
| 04 | import android.graphics.Color; |
| 05 | import android.os.Bundle; |
| 09 | public class HelloAndroid extends Activity { |
| 10 | ????/** Called when the activity is first created. */ |
| 12 | ????public void onCreate(Bundle savedInstanceState) { |
| 13 | ????????super.onCreate(savedInstanceState); |
| 15 | ????????CoverFlow cf = new CoverFlow(this); |
| 16 | ????????// cf.setBackgroundResource(R.drawable.shape); |
| 17 | ????????cf.setBackgroundColor(Color.BLACK); |
| 18 | ????????cf.setAdapter(new ImageAdapter(this)); |
| 19 | ????????ImageAdapter imageAdapter = 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); |
參考自:
http://www.eoeandroid.com/thread-70209-1-1.html
http://www.apkbus.com/android-18441-1-1.html
轉(zhuǎn)載于:https://www.cnblogs.com/ou10209019/archive/2012/07/30/2615861.html
總結(jié)
以上是生活随笔為你收集整理的Android实现CoverFlow效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。