zoukankan      html  css  js  c++  java
  • Android Gallery实现苹果的coverflow效果

    最近在学Gallery,功能是实现了,但是效果特别差,跟iphone的coverflow是没发比的,然后就在网上搜索了一些关于Gallery的高级用法什么的,网上很多实现了基于android的Gallery的coverflow效果,但看了源代码,我还是很多看不懂。(初学android,好多方法没看到过)后来我就按网上写的在自己的eclipes里运行了一下。在他代码的基础上实现了循环播放的效果。虽然结果出来了,但我还是一知半解的。(希望大家能给我个好的链接介绍这种效果的)。谢谢

    第一步:编写布局layout_grally.xml文件,具体代码如下:

    View Code
     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:orientation="vertical"
    4 android:layout_width="fill_parent"
    5 android:layout_height="fill_parent"
    6 android:background="#ffffff"
    7 >
    8 <cn.shaoyangjiang.com.GalleryFlow
    9 android:id="@+id/Gallery01"
    10 android:layout_width="fill_parent"
    11 android:layout_height="wrap_content"
    12 android:layout_centerInParent="true"
    13 android:spacing="-60px"/>
    14 </LinearLayout>

    第二步:在values文件夹下修改string.xml文件,一开始,我就是因为没修改这个文件,然后一直编译不出来,浪费了很长时间。总结出一点,拷别人写的代码也要拷全了,不然编译不会通过

    View Code
    1 <?xml version="1.0" encoding="utf-8"?>
    2 <resources>
    3 <string name="hello">Hello World, ActivityMain!</string>
    4 <string name="app_name">Gallery</string>
    5 </resources>

    第三步:编写主的ActivityMain.java文件,这个比较简单,主要是对Gallery设置Adapter就可以了,我想这个大家都应该看的懂,具体代码如下:

    View Code
     1 package cn.shaoyangjiang.com;
    2
    3 import android.app.Activity;
    4 import android.os.Bundle;
    5
    6 public class ActivityMain extends Activity {
    7 public void onCreate(Bundle savedInstanceState) {
    8 super.onCreate(savedInstanceState);
    9 setContentView(R.layout.layout_gallery);
    10 Integer[] images = { R.drawable.shao4,
    11 R.drawable.shao1, R.drawable.shao2, R.drawable.shao3,
    12 R.drawable.shao5,R.drawable.hawana_0,R.drawable.huanyinghei_14,
    13 R.drawable.huanyinghei_6,R.drawable.wulonghui_24,R.drawable.xuanfenghei_10};
    14
    15 ImageAdapter adapter = new ImageAdapter(this, images);
    16 adapter.createReflectedImages();
    17
    18 GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.Gallery01);
    19 galleryFlow.setAdapter(adapter);
    20
    21 }
    22 }

    第四步,编写ImageAdapter.java这个类,这个类也还算简单,继承BaseAdapter,重写getCount(),getItem(),getItems,getView(),这四个方法,我在这里对网上的源码稍微做了点修改,

    /*让Galllery循环播放的方法
     * 1. 使getCount方法返回一个很大的值。建议返回Integer.MAX_VALUE。,这个值可以到达20亿多
     * 2. 在getView方法中通过取余来循环取得resIds数组中的图像资源ID。
     * 3.循环Gallery参考http://blog.csdn.net/herryz/article/details/6141957
     */

    具体代码如下:

    View Code
      1 package cn.shaoyangjiang.com;
    2
    3 import android.content.Context;
    4 import android.content.res.Resources;
    5 import android.graphics.Bitmap;
    6 import android.graphics.BitmapFactory;
    7 import android.graphics.Canvas;
    8 import android.graphics.LinearGradient;
    9 import android.graphics.Matrix;
    10 import android.graphics.Paint;
    11 import android.graphics.PorterDuffXfermode;
    12 import android.graphics.Bitmap.Config;
    13 import android.graphics.PorterDuff.Mode;
    14 import android.graphics.Shader.TileMode;
    15 import android.view.View;
    16 import android.view.ViewGroup;
    17 import android.widget.BaseAdapter;
    18 import android.widget.ImageView;
    19 import android.widget.ImageView.ScaleType;
    20
    21 public class ImageAdapter extends BaseAdapter {
    22
    23 int mGalleryItemBackground;
    24 private Context mContext;
    25 private Integer[] mImageIds;
    26 private ImageView[] mImages;
    27
    28 public ImageAdapter(Context c, Integer[] ImageIds) {
    29 mContext = c;
    30 mImageIds = ImageIds;
    31 mImages = new ImageView[mImageIds.length];
    32 }
    33
    34 public boolean createReflectedImages() {
    35 final int reflectionGap = 4;
    36 int index = 0;
    37
    38 for (int imageId : mImageIds) {
    39 Bitmap originalImage = BitmapFactory.decodeResource(mContext
    40 .getResources(), imageId);
    41 int width = originalImage.getWidth();
    42 int height = originalImage.getHeight();
    43
    44 Matrix matrix = new Matrix();
    45 matrix.preScale(1, -1);
    46
    47 Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
    48 height / 2, width, height / 2, matrix, false);
    49
    50 Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
    51 (height + height / 2), Config.ARGB_8888);
    52
    53 Canvas canvas = new Canvas(bitmapWithReflection);
    54
    55 canvas.drawBitmap(originalImage, 0, 0, null);
    56
    57 Paint deafaultPaint = new Paint();
    58 canvas.drawRect(0, height, width, height + reflectionGap,
    59 deafaultPaint);
    60
    61 canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
    62
    63 Paint paint = new Paint();
    64 LinearGradient shader = new LinearGradient(0, originalImage
    65 .getHeight(), 0, bitmapWithReflection.getHeight()
    66 + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
    67
    68 paint.setShader(shader);
    69
    70 paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
    71
    72 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
    73 + reflectionGap, paint);
    74
    75 ImageView imageView = new ImageView(mContext);
    76 imageView.setImageBitmap(bitmapWithReflection);
    77 imageView.setLayoutParams(new GalleryFlow.LayoutParams(200, 350));
    78 // imageView.setScaleType(ScaleType.MATRIX);
    79 mImages[index++] = imageView;
    80 }
    81 return true;
    82 }
    83
    84 private Resources getResources() {
    85 // TODO Auto-generated method stub
    86 return null;
    87 }
    88
    89 public int getCount() {
    90 //return mImageIds.length;
    91 return Integer.MAX_VALUE;
    92 }
    93
    94 public Object getItem(int position) {
    95 return position;
    96 }
    97
    98 public long getItemId(int position) {
    99 return position;
    100 }
    101
    102 public View getView(int position, View convertView, ViewGroup parent) {
    103 return mImages[position%mImageIds.length];
    104 //return mImages[position];
    105 }
    106 //
    107 // public float getScale(boolean focused, int offset) {
    108 // return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
    109 // }
    110
    111 }

    第五步,也是最头疼,也是我看不懂的,我大致理解自定义一个类是继承了Gallery,贴上网上他们说的

    /*仅仅实现了图片的倒影效果还不够,因为在coverflow中图片切换是有旋转和缩放效果的,
     * 而自带的gallery中并没有实现。因此,我们扩展自带的gallery,实现自己的galleryflow。
     * 在原gallery类中,提供了一个方法getChildStaticTransformation()以实现对图片的变换。
     * 我们通过覆写这个方法并在其中调用自定义的transformImageBitmap(“每个图片与gallery中心的距离”)方法,
     * ,即可实现每个图片做相应的旋转和缩放。其中使用了camera和matrix用于视图变换
     *
     *  1. 成员函数

           mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
           mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
           mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
           其他的变量都可以无视

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

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

     具体代码如下:

    View Code
      1 package cn.shaoyangjiang.com;
    2
    3 import android.content.Context;
    4 import android.graphics.Camera;
    5 import android.graphics.Matrix;
    6 import android.util.AttributeSet;
    7 import android.util.Log;
    8 import android.view.View;
    9 import android.view.animation.Transformation;
    10 import android.widget.Gallery;
    11 import android.widget.ImageView;
    12
    13 public class GalleryFlow extends Gallery {
    14
    15 private Camera mCamera = new Camera();
    16 private int mMaxRotationAngle = 60;
    17 private int mMaxZoom = -120;
    18 private int mCoveflowCenter;
    19
    20 public GalleryFlow(Context context) {
    21 super(context);
    22 this.setStaticTransformationsEnabled(true);
    23 }
    24
    25 public GalleryFlow(Context context, AttributeSet attrs) {
    26 super(context, attrs);
    27 this.setStaticTransformationsEnabled(true);
    28 }
    29
    30 public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {
    31 super(context, attrs, defStyle);
    32 this.setStaticTransformationsEnabled(true);
    33 }
    34
    35 public int getMaxRotationAngle() {
    36 return mMaxRotationAngle;
    37 }
    38
    39 public void setMaxRotationAngle(int maxRotationAngle) {
    40 mMaxRotationAngle = maxRotationAngle;
    41 }
    42
    43 public int getMaxZoom() {
    44 return mMaxZoom;
    45 }
    46
    47 public void setMaxZoom(int maxZoom) {
    48 mMaxZoom = maxZoom;
    49 }
    50
    51 private int getCenterOfCoverflow() {
    52 return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
    53 + getPaddingLeft();
    54 }
    55
    56 private static int getCenterOfView(View view) {
    57 return view.getLeft() + view.getWidth() / 2;
    58 }
    59
    60 protected boolean getChildStaticTransformation(View child, Transformation t) {
    61
    62 final int childCenter = getCenterOfView(child);
    63 final int childWidth = child.getWidth();
    64 int rotationAngle = 0;
    65
    66 t.clear();
    67 t.setTransformationType(Transformation.TYPE_MATRIX);
    68 Log.v("tag", "getChildStaticTransformation>>>>>>>>>>>>>>>>>>>childCenter"+childCenter+">>>>>"+Math.abs((mCoveflowCenter-childCenter)/(childWidth)));
    69 if (childCenter == mCoveflowCenter) {
    70 transformImageBitmap((ImageView) child, t, 0);
    71 } else {
    72 if ((mCoveflowCenter - childCenter) > 0) {
    73 rotationAngle = (int) mMaxRotationAngle;
    74 } else {
    75 rotationAngle = (int) -mMaxRotationAngle;
    76 }
    77 if(Math.abs((mCoveflowCenter-childCenter)/(childWidth/2))==0){
    78 rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) /
    79 childWidth) * mMaxRotationAngle);
    80 }
    81
    82 transformImageBitmap((ImageView) child, t, rotationAngle);
    83 }
    84
    85 return true;
    86 }
    87
    88 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    89 mCoveflowCenter = getCenterOfCoverflow();
    90 super.onSizeChanged(w, h, oldw, oldh);
    91 }
    92
    93 private void transformImageBitmap(ImageView child, Transformation t,
    94 int rotationAngle) {
    95 mCamera.save();
    96 final Matrix imageMatrix = t.getMatrix();
    97 final int imageHeight = child.getLayoutParams().height;
    98 final int imageWidth = child.getLayoutParams().width;
    99 final int rotation = Math.abs(rotationAngle);
    100
    101 // 在Z轴上正向移动camera的视角,实际效果为放大图片。
    102 // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
    103 mCamera.translate(0.0f, 0.0f, 100.0f);
    104
    105 //// As the angle of the view gets less, zoom in
    106 // if (rotation < mMaxRotationAngle) {
    107 // float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
    108 // mCamera.translate(0.0f, 0.0f, zoomAmount);
    109 // }
    110
    111 // 在Y轴上旋转,对应图片竖向向里翻转。
    112 // 如果在X轴上旋转,则对应图片横向向里翻转。
    113 mCamera.rotateY(rotationAngle);
    114 mCamera.getMatrix(imageMatrix);
    115 imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
    116 imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
    117 mCamera.restore();
    118 }
    119 }

    显示演示效果:

    注:这个程序基本上没自己敲写,都是网上复制粘帖的,哈哈,水平还是差了点,不过一直在努力学习中。



     

  • 相关阅读:
    吴裕雄--天生自然java开发常用类库学习笔记:LinkedList类
    吴裕雄--天生自然java开发常用类库学习笔记:List接口
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:SSM(Spring+Spring MVC+MyBatis)框架整合搭建详细步骤
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:测试SSH框架分层整合及验证事务是否有效
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:SSH框架(Struts2+Spring+Hibernate)搭建整合详细步骤
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring声明式事务管理(基于Annotation注解方式实现)
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring声明式事务管理(基于XML方式实现)
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring事务管理接口PlatformTransactionManager、TransactionDefinition和TransactionStatus
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring JDBCTemplate简介
    吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring使用AspectJ开发AOP基于XML和基于Annotation
  • 原文地址:https://www.cnblogs.com/shaoyangjiang/p/2367734.html
Copyright © 2011-2022 走看看