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

时间:2023-02-04 16:18:19

 

 

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


首先看效果:

 

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

 

 

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

 

来看实现:FlingImageDemo

 

实现主要就是自定义View

 

  1. import android.content.Context;  
  2. import android.graphics.Bitmap;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Color;  
  5. import android.graphics.Paint;  
  6. import android.graphics.Rect;  
  7. import android.util.AttributeSet;  
  8. import android.view.View;  
  9. import android.view.animation.Animation;  
  10. import android.view.animation.LinearInterpolator;  
  11. import android.view.animation.Transformation;  
  12. /** 
  13.  * 照片浏览View 
  14.  */  
  15. public class FlingView extends View{  
  16.       
  17.     private Bitmap bitmap;  
  18.     private Bitmap nBitmap;  
  19.     private Bitmap fBitmap;  
  20.       
  21.     public int OffsetX = 0;  
  22.     public int OffsetY = 0;  
  23.       
  24.     public static int postion = 0;  
  25.     int mLastFlingX = 0;  
  26.     boolean OffsetRight = false;  
  27.       
  28.     private Bitmap[] bitmaps ;  
  29.       
  30.     public FlingView(Context context, AttributeSet attrs) {  
  31.         super(context, attrs);  
  32.           
  33.     }  
  34.       
  35.     public FlingView(Context context,Bitmap[] bitmaps){  
  36.         super(context);  
  37.         this.bitmaps = bitmaps;  
  38.         bitmap = getBitmap(0);  
  39.         nBitmap = getBitmap(1);  
  40.     }  
  41.       
  42.     @Override  
  43.     public void draw(Canvas canvas) {  
  44.         Paint p = new Paint();  
  45.         canvas.drawColor(Color.BLACK);  
  46.         if (OffsetX < 0) {  
  47.             if (nBitmap != null) {  
  48.                 Rect rectTemp = new Rect(FlingImageDemo.SCREEN_WIDTH+15 + OffsetX,0,FlingImageDemo.SCREEN_WIDTH+15 + OffsetX+FlingImageDemo.SCREEN_WIDTH,FlingImageDemo.SCREEN_HEIGHT);  
  49.                 canvas.drawBitmap(nBitmap, null, rectTemp, p);  
  50.             }  
  51.         } else if (OffsetX > 0) {  
  52.             if (fBitmap != null) {  
  53.                 Rect rectTemp = new Rect(-FlingImageDemo.SCREEN_WIDTH-15 + OffsetX,0,-FlingImageDemo.SCREEN_WIDTH-15 + OffsetX+FlingImageDemo.SCREEN_WIDTH,FlingImageDemo.SCREEN_HEIGHT);  
  54.                 canvas.drawBitmap(fBitmap, null, rectTemp, p);  
  55.             }  
  56.         }  
  57.         if(bitmap != null){  
  58.             Rect rectTemp = new Rect(OffsetX,OffsetY,OffsetX+FlingImageDemo.SCREEN_WIDTH,OffsetY+FlingImageDemo.SCREEN_HEIGHT);  
  59.             canvas.drawBitmap(bitmap, null, rectTemp, p);  
  60.         }  
  61.     }  
  62.       
  63.       
  64.       
  65.     public void handleScroll(int deltaX) {  
  66.         if (deltaX > 0) {  
  67.             OffsetX -= -deltaX;  
  68.         } else {  
  69.             OffsetX += deltaX;  
  70.         }  
  71.         invalidate();  
  72.     }  
  73.       
  74.     //标记为可以切换到下一张   
  75.     boolean flag = false;  
  76.     //标记为需要向右滑动   
  77.     boolean flag1 = false;  
  78.     //标记为需要向左滑动   
  79.     boolean flag2 = false;  
  80.       
  81.       
  82.     class MyAnimation extends Animation{  
  83.           
  84.         private int temp;  
  85.           
  86.         @Override  
  87.         public void initialize(int width, int height, int parentWidth,  
  88.                 int parentHeight) {  
  89.             temp = OffsetX;  
  90.             super.initialize(width, height, parentWidth, parentHeight);  
  91.             setDuration(500);  
  92.             setFillAfter(true);  
  93.             setInterpolator(new LinearInterpolator());  
  94.         }  
  95.           
  96.         @Override  
  97.         protected void applyTransformation(float interpolatedTime,  
  98.                 Transformation t) {  
  99. //          Log.i("bb", "OffsetX==>"+OffsetX);   
  100.             //需要滑动图片时根据方向来变换OffsetX大小   
  101.             if(flag){  
  102.                 if(temp>0){  
  103.                     OffsetX = (int) ((FlingImageDemo.SCREEN_WIDTH-temp)*interpolatedTime+temp);  
  104.                 }else{  
  105.                     OffsetX = (int) ((-FlingImageDemo.SCREEN_WIDTH-temp)*interpolatedTime+temp);  
  106.                 }  
  107.             //不需要变换的情况   
  108.             }else{  
  109.                 OffsetX = (int) (temp*(1-interpolatedTime));  
  110.             }  
  111.               
  112.             invalidate();  
  113.         }  
  114.     }  
  115.     //动画结束后需要做一些工作   
  116.     @Override  
  117.     protected void onAnimationEnd() {  
  118.         if (flag1) {  
  119.             nBitmap = bitmap;  
  120.             bitmap = fBitmap;  
  121.             fBitmap = null;  
  122.             postion = postion - 1;  
  123.         } else if (flag2) {  
  124.             fBitmap = bitmap;  
  125.             bitmap = nBitmap;  
  126.             nBitmap = null;  
  127.             postion = postion + 1;  
  128.         }  
  129.         flag1 = false;  
  130.         flag2 = false;  
  131.         OffsetX = 0;  
  132.         if(fBitmap == null && OffsetX == 0){  
  133.             if (postion > 0) {  
  134.                 fBitmap = getBitmap(postion-1);  
  135.             }  
  136.               
  137.         }else if(nBitmap == null && OffsetX==0){  
  138.             if (postion < bitmaps.length-1) {  
  139.                 nBitmap = getBitmap(postion+1);  
  140.             }  
  141.         }  
  142.         clearAnimation();  
  143.         flag = false;  
  144.     }  
  145.       
  146.     public void onFling(int paramFloat1) {  
  147.         if (OffsetX > FlingImageDemo.SCREEN_WIDTH/3) {  
  148.             if (fBitmap != null) {  
  149.                 flag = true;  
  150.                 flag1 = true;  
  151.             }  
  152.         } else if (OffsetX < -FlingImageDemo.SCREEN_WIDTH/3) {  
  153.             if (nBitmap != null) {  
  154.                 flag = true;  
  155.                 flag2 = true;  
  156.             }  
  157.         }  
  158.         //开始动画效果   
  159.         startAnimation(new MyAnimation());  
  160.         invalidate();  
  161.           
  162.     }  
  163.     /** 
  164.      * 获得当前位置的图片 
  165.      * @param currentPos 
  166.      * @return 
  167.      */  
  168.     public Bitmap getBitmap(int currentPos) {  
  169.         if (currentPos > bitmaps.length-1) {  
  170.             return null;  
  171.         }  
  172.         Bitmap currBitmap = bitmaps[currentPos];  
  173.         OffsetX = 0;  
  174.         OffsetY = 0;  
  175.            
  176.         return currBitmap;  
  177.     }  
  178. }  

 

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


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

 

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

 

  1. import android.app.Activity;  
  2. import android.graphics.Bitmap;  
  3. import android.graphics.BitmapFactory;  
  4. import android.os.Bundle;  
  5. import android.util.DisplayMetrics;  
  6. import android.view.GestureDetector;  
  7. import android.view.MotionEvent;  
  8. import android.view.GestureDetector.OnGestureListener;  
  9. public class FlingImageDemo extends Activity  implements OnGestureListener{  
  10.       
  11.     private FlingView flingView;  
  12.       
  13.     private  GestureDetector myGesture;  
  14.       
  15.       
  16.       
  17.     public static int SCREEN_WIDTH;  
  18.     public static int SCREEN_HEIGHT;  
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.           
  22.         DisplayMetrics  dm = new DisplayMetrics();  
  23.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  24.           
  25.         //获得手机的宽带和高度像素单位为px   
  26.         SCREEN_WIDTH = dm.widthPixels;  
  27.         SCREEN_HEIGHT = dm.heightPixels;   
  28.         //位图资源  不要小于2张   
  29.         Bitmap[] bitmaps = {  
  30.                 BitmapFactory  
  31.                         .decodeResource(getResources(), R.drawable.g1),  
  32.                 BitmapFactory  
  33.                         .decodeResource(getResources(), R.drawable.g3),  
  34.                 BitmapFactory  
  35.                         .decodeResource(getResources(), R.drawable.g4),  
  36. //              BitmapFactory   
  37. //                      .decodeResource(getResources(), R.drawable.g7),   
  38.                 BitmapFactory  
  39.                         .decodeResource(getResources(), R.drawable.g8) };  
  40.           
  41.         super.onCreate(savedInstanceState);  
  42.         flingView = new FlingView(this,bitmaps);  
  43.         setContentView(flingView);  
  44.         myGesture = new GestureDetector(this);  
  45.     }  
  46.     @Override  
  47.     public boolean onTouchEvent(MotionEvent event) {  
  48.           
  49.         switch (event.getAction()) {  
  50.         case MotionEvent.ACTION_UP:  
  51.             flingView.onFling(0);  
  52.             break;  
  53.         }  
  54.           
  55.         return myGesture.onTouchEvent(event);  
  56.     }  
  57.     @Override  
  58.     public boolean onDown(MotionEvent e) {  
  59.         // TODO Auto-generated method stub   
  60.         return false;  
  61.     }  
  62.     //手势完成后调用   
  63.     @Override  
  64.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  65.             float velocityY) {  
  66.         flingView.onFling((int)-velocityX);  
  67.         return true;  
  68.     }  
  69.     @Override  
  70.     public void onLongPress(MotionEvent e) {  
  71.         // TODO Auto-generated method stub   
  72.           
  73.     }  
  74.     //滑动过程一直在调用   
  75.     @Override  
  76.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  77.             float distanceY) {  
  78.         flingView.handleScroll(-1*(int)distanceX);  
  79.         return true;  
  80.     }  
  81.     @Override  
  82.     public void onShowPress(MotionEvent e) {  
  83.         // TODO Auto-generated method stub   
  84.           
  85.     }  
  86.     @Override  
  87.     public boolean onSingleTapUp(MotionEvent e) {  
  88.         // TODO Auto-generated method stub   
  89.         return false;  
  90.     }  

 

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