用的Android系统自带的相机软件,他的照片查看首先是一个Galery,点击查看后也是类似这个效果,感觉体验挺好,仿照效果自己做了下demo
首先看效果:
然后就是加上的滑动动画效果
来看实现:FlingImageDemo
实现主要就是自定义View
- importandroid.content.Context;
- importandroid.graphics.Bitmap;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.Rect;
- importandroid.util.AttributeSet;
- importandroid.view.View;
- importandroid.view.animation.Animation;
- importandroid.view.animation.LinearInterpolator;
- importandroid.view.animation.Transformation;
- /**
- *照片浏览View
- */
- publicclassFlingViewextendsView{
- privateBitmapbitmap;
- privateBitmapnBitmap;
- privateBitmapfBitmap;
- publicintOffsetX=0;
- publicintOffsetY=0;
- publicstaticintpostion=0;
- intmLastFlingX=0;
- booleanOffsetRight=false;
- privateBitmap[]bitmaps;
- publicFlingView(Contextcontext,AttributeSetattrs){
- super(context,attrs);
- }
- publicFlingView(Contextcontext,Bitmap[]bitmaps){
- super(context);
- this.bitmaps=bitmaps;
- bitmap=getBitmap(0);
- nBitmap=getBitmap(1);
- }
- @Override
- publicvoiddraw(Canvascanvas){
- Paintp=newPaint();
- canvas.drawColor(Color.BLACK);
- if(OffsetX<0){
- if(nBitmap!=null){
- RectrectTemp=newRect(FlingImageDemo.SCREEN_WIDTH+15+OffsetX,0,FlingImageDemo.SCREEN_WIDTH+15+OffsetX+FlingImageDemo.SCREEN_WIDTH,FlingImageDemo.SCREEN_HEIGHT);
- canvas.drawBitmap(nBitmap,null,rectTemp,p);
- }
- }elseif(OffsetX>0){
- if(fBitmap!=null){
- RectrectTemp=newRect(-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){
- RectrectTemp=newRect(OffsetX,OffsetY,OffsetX+FlingImageDemo.SCREEN_WIDTH,OffsetY+FlingImageDemo.SCREEN_HEIGHT);
- canvas.drawBitmap(bitmap,null,rectTemp,p);
- }
- }
- publicvoidhandleScroll(intdeltaX){
- if(deltaX>0){
- OffsetX-=-deltaX;
- }else{
- OffsetX+=deltaX;
- }
- invalidate();
- }
- //标记为可以切换到下一张
- booleanflag=false;
- //标记为需要向右滑动
- booleanflag1=false;
- //标记为需要向左滑动
- booleanflag2=false;
- classMyAnimationextendsAnimation{
- privateinttemp;
- @Override
- publicvoidinitialize(intwidth,intheight,intparentWidth,
- intparentHeight){
- temp=OffsetX;
- super.initialize(width,height,parentWidth,parentHeight);
- setDuration(500);
- setFillAfter(true);
- setInterpolator(newLinearInterpolator());
- }
- @Override
- protectedvoidapplyTransformation(floatinterpolatedTime,
- Transformationt){
- //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
- protectedvoidonAnimationEnd(){
- if(flag1){
- nBitmap=bitmap;
- bitmap=fBitmap;
- fBitmap=null;
- postion=postion-1;
- }elseif(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);
- }
- }elseif(nBitmap==null&&OffsetX==0){
- if(postion<bitmaps.length-1){
- nBitmap=getBitmap(postion+1);
- }
- }
- clearAnimation();
- flag=false;
- }
- publicvoidonFling(intparamFloat1){
- if(OffsetX>FlingImageDemo.SCREEN_WIDTH/3){
- if(fBitmap!=null){
- flag=true;
- flag1=true;
- }
- }elseif(OffsetX<-FlingImageDemo.SCREEN_WIDTH/3){
- if(nBitmap!=null){
- flag=true;
- flag2=true;
- }
- }
- //开始动画效果
- startAnimation(newMyAnimation());
- invalidate();
- }
- /**
- *获得当前位置的图片
- *@paramcurrentPos
- *@return
- */
- publicBitmapgetBitmap(intcurrentPos){
- if(currentPos>bitmaps.length-1){
- returnnull;
- }
- BitmapcurrBitmap=bitmaps[currentPos];
- OffsetX=0;
- OffsetY=0;
- returncurrBitmap;
- }
- }
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了
- importandroid.app.Activity;
- importandroid.graphics.Bitmap;
- importandroid.graphics.BitmapFactory;
- importandroid.os.Bundle;
- importandroid.util.DisplayMetrics;
- importandroid.view.GestureDetector;
- importandroid.view.MotionEvent;
- importandroid.view.GestureDetector.OnGestureListener;
- publicclassFlingImageDemoextendsActivityimplementsOnGestureListener{
- privateFlingViewflingView;
- privateGestureDetectormyGesture;
- publicstaticintSCREEN_WIDTH;
- publicstaticintSCREEN_HEIGHT;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- DisplayMetricsdm=newDisplayMetrics();
- 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=newFlingView(this,bitmaps);
- setContentView(flingView);
- myGesture=newGestureDetector(this);
- }
- @Override
- publicbooleanonTouchEvent(MotionEventevent){
- switch(event.getAction()){
- caseMotionEvent.ACTION_UP:
- flingView.onFling(0);
- break;
- }
- returnmyGesture.onTouchEvent(event);
- }
- @Override
- publicbooleanonDown(MotionEvente){
- //TODOAuto-generatedmethodstub
- returnfalse;
- }
- //手势完成后调用
- @Override
- publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,
- floatvelocityY){
- flingView.onFling((int)-velocityX);
- returntrue;
- }
- @Override
- publicvoidonLongPress(MotionEvente){
- //TODOAuto-generatedmethodstub
- }
- //滑动过程一直在调用
- @Override
- publicbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,
- floatdistanceY){
- flingView.handleScroll(-1*(int)distanceX);
- returntrue;
- }
- @Override
- publicvoidonShowPress(MotionEvente){
- //TODOAuto-generatedmethodstub
- }
- @Override
- publicbooleanonSingleTapUp(MotionEvente){
- //TODOAuto-generatedmethodstub
- returnfalse;
- }
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中分别调用
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; } } 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; }