Android进阶:实现android系统自带查看照片动画效果 类似Gallery手势滑动

用的Android系统自带的相机软件,他的照片查看首先是一个Galery,点击查看后也是类似这个效果,感觉体验挺好,仿照效果自己做了下demo


首先看效果:

Android进阶:实现android系统自带查看照片动画效果 类似Gallery手势滑动Android进阶:实现android系统自带查看照片动画效果 类似Gallery手势滑动

然后就是加上的滑动动画效果

来看实现:FlingImageDemo

实现主要就是自定义View

import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; /** * 照片浏览View */ public class FlingView extends View{ private Bitmap bitmap; private Bitmap nBitmap; private Bitmap fBitmap; public int OffsetX = 0; public int OffsetY = 0; public static int postion = 0; int mLastFlingX = 0; boolean OffsetRight = false; private Bitmap[] bitmaps ; public FlingView(Context context, AttributeSet attrs) { super(context, attrs); } public FlingView(Context context,Bitmap[] bitmaps){ super(context); this.bitmaps = bitmaps; bitmap = getBitmap(0); nBitmap = getBitmap(1); } @Override public void draw(Canvas canvas) { Paint p = new Paint(); canvas.drawColor(Color.BLACK); if (OffsetX < 0) { if (nBitmap != null) { Rect rectTemp = new Rect(FlingImageDemo.SCREEN_WIDTH+15 + OffsetX,0,FlingImageDemo.SCREEN_WIDTH+15 + OffsetX+FlingImageDemo.SCREEN_WIDTH,FlingImageDemo.SCREEN_HEIGHT); canvas.drawBitmap(nBitmap, null, rectTemp, p); } } else if (OffsetX > 0) { if (fBitmap != null) { Rect rectTemp = new Rect(-FlingImageDemo.SCREEN_WIDTH-15 + OffsetX,0,-FlingImageDemo.SCREEN_WIDTH-15 + OffsetX+FlingImageDemo.SCREEN_WIDTH,FlingImageDemo.SCREEN_HEIGHT); canvas.drawBitmap(fBitmap, null, rectTemp, p); } } if(bitmap != null){ Rect rectTemp = new Rect(OffsetX,OffsetY,OffsetX+FlingImageDemo.SCREEN_WIDTH,OffsetY+FlingImageDemo.SCREEN_HEIGHT); canvas.drawBitmap(bitmap, null, rectTemp, p); } } public void handleScroll(int deltaX) { if (deltaX > 0) { OffsetX -= -deltaX; } else { OffsetX += deltaX; } invalidate(); } //标记为可以切换到下一张 boolean flag = false; //标记为需要向右滑动 boolean flag1 = false; //标记为需要向左滑动 boolean flag2 = false; class MyAnimation extends Animation{ private int temp; @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { temp = OffsetX; super.initialize(width, height, parentWidth, parentHeight); setDuration(500); setFillAfter(true); setInterpolator(new LinearInterpolator()); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // Log.i("bb", "OffsetX==>"+OffsetX); //需要滑动图片时根据方向来变换OffsetX大小 if(flag){ if(temp>0){ OffsetX = (int) ((FlingImageDemo.SCREEN_WIDTH-temp)*interpolatedTime+temp); }else{ OffsetX = (int) ((-FlingImageDemo.SCREEN_WIDTH-temp)*interpolatedTime+temp); } //不需要变换的情况 }else{ OffsetX = (int) (temp*(1-interpolatedTime)); } invalidate(); } } //动画结束后需要做一些工作 @Override protected void onAnimationEnd() { if (flag1) { nBitmap = bitmap; bitmap = fBitmap; fBitmap = null; postion = postion - 1; } else if (flag2) { fBitmap = bitmap; bitmap = nBitmap; nBitmap = null; postion = postion + 1; } flag1 = false; flag2 = false; OffsetX = 0; if(fBitmap == null && OffsetX == 0){ if (postion > 0) { fBitmap = getBitmap(postion-1); } }else if(nBitmap == null && OffsetX==0){ if (postion < bitmaps.length-1) { nBitmap = getBitmap(postion+1); } } clearAnimation(); flag = false; } public void onFling(int paramFloat1) { if (OffsetX > FlingImageDemo.SCREEN_WIDTH/3) { if (fBitmap != null) { flag = true; flag1 = true; } } else if (OffsetX < -FlingImageDemo.SCREEN_WIDTH/3) { if (nBitmap != null) { flag = true; flag2 = true; } } //开始动画效果 startAnimation(new MyAnimation()); invalidate(); } /** * 获得当前位置的图片 * @param currentPos * @return */ public Bitmap getBitmap(int currentPos) { if (currentPos > bitmaps.length-1) { return null; } Bitmap currBitmap = bitmaps[currentPos]; OffsetX = 0; OffsetY = 0; return currBitmap; } }

中间通过 MyAnimation 来实现自定义的动画 主要重写applyTransformation方法


以及onAnimationEnd方法中 在动画结束后做的一些细节操作了 很简单 就是逻辑搞得有点乱了~~

然后创建Activity 创建View 传入图片资源就OK了

import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.GestureDetector.OnGestureListener; public class FlingImageDemo extends Activity implements OnGestureListener{ private FlingView flingView; private GestureDetector myGesture; public static int SCREEN_WIDTH; public static int SCREEN_HEIGHT; @Override public void onCreate(Bundle savedInstanceState) { DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); //获得手机的宽带和高度像素单位为px SCREEN_WIDTH = dm.widthPixels; SCREEN_HEIGHT = dm.heightPixels; //位图资源 不要小于2张 Bitmap[] bitmaps = { BitmapFactory .decodeResource(getResources(), R.drawable.g1), BitmapFactory .decodeResource(getResources(), R.drawable.g3), BitmapFactory .decodeResource(getResources(), R.drawable.g4), // BitmapFactory // .decodeResource(getResources(), R.drawable.g7), BitmapFactory .decodeResource(getResources(), R.drawable.g8) }; super.onCreate(savedInstanceState); flingView = new FlingView(this,bitmaps); setContentView(flingView); myGesture = new GestureDetector(this); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: flingView.onFling(0); break; } return myGesture.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } //手势完成后调用 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { flingView.onFling((int)-velocityX); return true; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } //滑动过程一直在调用 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { flingView.handleScroll(-1*(int)distanceX); return true; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; }

实现OnGestureListener接口 在方法onFling和onScroll中分别调用

仅仅这个功能 后面的慢慢添加吧