Gallery仿图像集浏览 (源码)

package yy.android.callery;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;

public class CalleryActivity extends Activity implements OnGestureListener {

    private FlingView flingView;//自定义View
    private GestureDetector myGesture;//用来注册事件的

    public static int deviceScreenWidth;
    public static int deviceScreenHeight;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 鑾峰緱鎵嬫満鐨勫甯﹀拰楂樺害鍍忕礌鍗曚綅涓簆x
        DisplayMetrics dm = new DisplayMetrics();//创建一个结构体来描述显示图片
        getWindowManager().getDefaultDisplay().getMetrics(dm);//获得一个结结构体
        deviceScreenWidth   = dm.widthPixels;//结构体的绝对像素宽
        deviceScreenHeight = dm.heightPixels;//结构体的绝对像素高
        Log.i("LOG", "Activity --> deviceScreenWidth = " + deviceScreenWidth + "; deviceScreenHeight = " + deviceScreenHeight);
        
        Bitmap[] bitmaps = {
                //从源文件里解析出里面的位图
                BitmapFactory.decodeResource(getResources(), R.drawable.img1),
                BitmapFactory.decodeResource(getResources(), R.drawable.img2),
                BitmapFactory.decodeResource(getResources(), R.drawable.img3),
                BitmapFactory.decodeResource(getResources(), R.drawable.img4),
                BitmapFactory.decodeResource(getResources(), R.drawable.img5) };

        myGesture = new GestureDetector(this);//手势监听器
        flingView = new FlingView(this, bitmaps);
        setContentView(flingView);//使用flingView作为布局文件
        Log.i("LOG", "Layout finished!!!");
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            flingView.onFling(0);//当用户松开手后 ,offsetX = 0
            break;
        }
        Log.i("LOG", "TOUCH!!!");
        //Detector注册Event事件,如果不注册是不会回调那些相应动作的方法的
        return myGesture.onTouchEvent(event);
    }

    public boolean onDown(MotionEvent e) {
        return false;
    }
    //滑动时触发
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.i("LOG", "velocityX = " + velocityX + "; velocityY = " + velocityY);
        flingView.onFling(-1 * (int)velocityX);
    //    Log.i("LOG","offsetX = "+ offsetX );
        return true;
    }
    //长按是触发
    public void onLongPress(MotionEvent e) {
    }
    //滚动时触发,(按着拖动时,会不断触发此方法,当松开手时,就触发onFling)
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        Log.i("LOG", "distanceX = " + distanceX + "; distanceY = " + distanceY);
        flingView.handleScroll(-1 * (int) distanceX);
        return true;
    }

    public void onShowPress(MotionEvent e) {
    }

    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

}

//

package yy.android.callery;

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.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

public class FlingView extends View {

    private Bitmap bitmap;
    private Bitmap nBitmap;
    private Bitmap fBitmap;

    public int offsetX = 0;
    public int offsetY = 0;
    public int postion = 0;//位图的位置从0开始

    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) {
        Log.i("LOG", "Draw!!!");
        Paint paint = new Paint();//画笔
        Rect rect = new Rect();//矩形
        canvas.drawColor(Color.BLACK);//过度颜色

        // 当前位图不为空,这段主要是绘制当前图的,如果滑动的,则只绘制剩下的部分,其余部分黑色
        if (bitmap != null) {
            int left = offsetX;//初始化状态,X方向的偏移
            int top = offsetY;//初始化状态,Y方向的偏移
            //注意,如果右边的坐标超过了平幕的宽度,则图片会被拉宽到有一部分是不可见的
            int right = offsetX + CalleryActivity.deviceScreenWidth;//位图的右边位置
            int bottom = offsetY + CalleryActivity.deviceScreenHeight;//位图底部位置
            //设置矩形区域的边界
            rect.set(left, top, right, bottom);
            //绘制图片出来
            canvas.drawBitmap(bitmap, null, rect, paint);
        }
        
        //当向左滑动时,这段是绘制相邻图片的,填充上面那段的黑色部分(填右)
        if (offsetX < 0) {
            //而且右边有位图存在的话
            if (nBitmap != null) {
                //以下式里的10是两张图片之间的空隙,注意此时X偏移为负数
                int left = CalleryActivity.deviceScreenWidth + 15 + offsetX;
                int top = 0;
                int right = left + CalleryActivity.deviceScreenWidth;
                int bottom = CalleryActivity.deviceScreenHeight;
                rect.set(left, top, right, bottom);
                canvas.drawBitmap(nBitmap, null, rect, paint);
            }
        //向右滑动时(填左)
        } else if (offsetX > 0) {
            //而且左边有位图存在
            if (fBitmap != null) {
                int left = -CalleryActivity.deviceScreenWidth - 15 + offsetX;
                int top = 0;
                int right = left + CalleryActivity.deviceScreenWidth;
                int bottom = CalleryActivity.deviceScreenWidth;
                rect.set(left, top, right, bottom);
                canvas.drawBitmap(fBitmap, null, rect, paint);
            }
        }
    }
    //滚动时触发
    public void handleScroll(int deltaX) {
        if (deltaX > 0) {//获得当前的偏移量
            offsetX -= -deltaX;
        } else {
            offsetX += deltaX;
        }
        Log.i("LOG", "HandleScroll!!!");
        invalidate();//通知系统重绘
    }

    /*@Override
    protected void onDraw(Canvas canvas) {
        Log.i("LOG","onDraw!!!");
        super.onDraw(canvas);
    }*/

    boolean isFling = false;        //是否正在滑动
    boolean isFlingRight = false;    //正在向右滑动
    boolean isFlingLeft = false;    //正在向左滑动

    class MyAnimation extends Animation {//动画类
        private int tmpOffsetX;

        @Override//初始化动画尺寸,和相对动画父框的尺寸
        public void initialize(int width, int height, int parentWidth, int parentHeight) {
            tmpOffsetX = offsetX;//临时偏移量
            super.initialize(width, height, parentWidth, parentHeight);
            setDuration(500);//动画的持续时间
            setFillAfter(true);//
            setInterpolator(new LinearInterpolator());//设置动画的加速度
        }

        @Override//在动画播放时不断的调用,直到interpolatedTime等于1.0
        protected void applyTransformation(float interpolatedTime, Transformation t) {
             Log.i("LOG", "interpolatedTime ==>"+interpolatedTime);
             //Log.i("LOG", "interpolatedTime ==>"+interpolatedTime);
            if (isFling) {//正在滑动                
                if (tmpOffsetX > 0) {//正在向右滑动        
                    offsetX = (int) ((CalleryActivity.deviceScreenWidth - tmpOffsetX) * interpolatedTime + tmpOffsetX);
                } else {//正在向左滑动            
                    offsetX = (int) ((-CalleryActivity.deviceScreenWidth - tmpOffsetX) * interpolatedTime + tmpOffsetX);
                }
            } else {//当下一张或前一张,没有图片的时候,返回原图        
                offsetX = (int) (tmpOffsetX * (1 - interpolatedTime));
            }
            invalidate();//重绘
        }
    }

    //动画结束后会回调,interpolatedTime==1.0 的时候,为下次的动作做准备
    @Override
    protected void onAnimationEnd() {
        Log.i("LOG", "END!!!");
        if (isFlingRight) {    //正在向右滑动
            nBitmap = bitmap;
            bitmap = fBitmap;
            fBitmap = null;
            postion = postion - 1;
        } else if (isFlingLeft) {//向左滑动
            fBitmap = bitmap;
            bitmap = nBitmap;
            nBitmap = null;
            postion = postion + 1;
        }
        
        isFlingRight = false;            
        isFlingLeft = false;
        isFling = 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();    //清除动画    ,如果不清楚的话动画会一直的播放    
    }
    
    /** 返回对应CurrentPos的位图*/
    public Bitmap getBitmap(int currentPos) {
        if (currentPos > bitmaps.length - 1) {
            return null;
        }
        //设置为当前位图,和设置它的偏移量
        Bitmap currBitmap = bitmaps[currentPos];
        offsetX = 0;
        offsetY = 0;

        return currBitmap;
    }
 
    public void onFling(int paramFloat1) {
        Log.i("LOG", "FIleView offsetX = "+offsetX );
        if (offsetX > CalleryActivity.deviceScreenWidth / 5) {
            //当偏移量大于以上值时,而起当前位图的左边还有图片的话就设置滑动标志位
            if (fBitmap != null) {
                isFling = true;
                isFlingRight = true;
            }
        } else if (offsetX < -CalleryActivity.deviceScreenWidth / 5) {
            if (nBitmap != null) {
                isFling = true;
                isFlingLeft = true;
            }
        }//开始播放动画
        startAnimation(new MyAnimation());
    }
}/另外还要在drawble里加上图片文件(.jpg)

还有一个问题就是,当调用invalidate()通知系统重绘时,为什么触发的是draw方法而不是onDraw方法呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值