第一步:创建手势基类:

public abstract class BaseGuestureDetector {    /** 进行中的手势   */    protected boolean mIsGestureMoving;    /** 先前的事件    */    protected MotionEvent mPreMotionEvent;    /** 当前的事件    */    protected MotionEvent mCurrentMotionEvent;    public Context mContext;    public BaseGuestureDetector(Context context){        mContext = context;    }    public boolean onTouchEvent(MotionEvent event){        if (!mIsGestureMoving) {            handleStartProgressEvent(event);        }else {            handleInProgressEvent(event);        }        return true;    }    protected abstract void handleInProgressEvent(MotionEvent event);    protected abstract void handleStartProgressEvent(MotionEvent event);    protected abstract void updateStateByEvent(MotionEvent event);    protected void resetState(){        if (mPreMotionEvent != null) {            mPreMotionEvent.recycle();            mPreMotionEvent = null;        }        if (mCurrentMotionEvent != null) {            mCurrentMotionEvent.recycle();            mCurrentMotionEvent = null;        }        mIsGestureMoving = false;    }}

第二步:根据基类创建手势类

public class MoveGestureDetector extends BaseGuestureDetector {    /** 当前的手指位置 */    private PointF mCurrentPointF;    /** 上次的手指位置 */    private PointF mPrePointF;    /** 用于记录最终结果,并返回 */    private PointF mExtenalPointer = new PointF();    private OnMoveGestureListener mListener;    public MoveGestureDetector(Context context, OnMoveGestureListener listener) {        super(context);        this.mListener = listener;    }    /**     * 处理正在进行的动作     */    @Override    protected void handleInProgressEvent(MotionEvent event) {        int action = event.getAction() & MotionEvent.ACTION_MASK;        switch (action) {        // 手指弹起与离开时        case MotionEvent.ACTION_CANCEL:        case MotionEvent.ACTION_UP:            mListener.onMoveEnd(this);            resetState();            break;        // 手指移动        case MotionEvent.ACTION_MOVE:            updateStateByEvent(event);            boolean move = mListener.onMove(this);            if (move) {                mPreMotionEvent.recycle();                mPreMotionEvent = MotionEvent.obtain(event);            }            break;        default:            break;        }    }    /**     * 处理开始的事件     */    @Override    protected void handleStartProgressEvent(MotionEvent event) {        int action = event.getAction() & MotionEvent.ACTION_MASK;        switch (action) {        case MotionEvent.ACTION_DOWN:            // 防止没有接收到CANCEL or UP ,保险起见            resetState();            // 初始化            mPreMotionEvent = MotionEvent.obtain(event);            updateStateByEvent(event);            break;        case MotionEvent.ACTION_MOVE:            mIsGestureMoving = mListener.onMoveBegin(this);            break;        default:            break;        }    }    @Override    protected void updateStateByEvent(MotionEvent event) {        final MotionEvent prev = mPreMotionEvent;        // 计算开始点的位置        mPrePointF = caculateFocalPointer(prev);        mCurrentPointF = caculateFocalPointer(event);        Log.e("TAG", mPrePointF.toString() + " ,  " + mCurrentPointF);        // 是否跳过这个点,如果前后手指数不一样        boolean mSkipThisMoveEvent = prev.getPointerCount() != event.getPointerCount();        // 如果是无效的设置为0        mExtenalPointer.x = mSkipThisMoveEvent ? 0 : mCurrentPointF.x - mPrePointF.x;        mExtenalPointer.y = mSkipThisMoveEvent ? 0 : mCurrentPointF.y - mPrePointF.y;    }    /**     * 根据event计算多指中心点     *      * @param event     * @return     */    private PointF caculateFocalPointer(MotionEvent event) {        final int count = event.getPointerCount();        float x = 0, y = 0;        for (int i = 0; i < count; i++) {            x += event.getX(i);            y += event.getY(i);        }        // 取手指的中心点        x = x / count;        y = y / count;        return new PointF(x, y);    }    /**     * 向外暴露的两个方法,获得移动中的位置     *      * @return     */    public float getMoveX() {        return mExtenalPointer.x;    }    public float getMoveY() {        return mExtenalPointer.y;    }    /**     * 回调函数     *      * @Project App_View     * @Package com.android.view.largeimageview     * @author chenlin     * @version 1.0     * @Note TODO     */    public interface OnMoveGestureListener {        /**         * 手指开始移动         *          * @param detector         * @return         */        public boolean onMoveBegin(MoveGestureDetector detector);        /**         * 手指移动中         *          * @param detector         * @return         */        public boolean onMove(MoveGestureDetector detector);        /**         * 移动结束         *          * @param detector         */        public void onMoveEnd(MoveGestureDetector detector);    }    public static class SimpleMoveGestureDetector implements OnMoveGestureListener {        @Override        public boolean onMoveBegin(MoveGestureDetector detector) {            return true;        }        @Override        public boolean onMove(MoveGestureDetector detector) {            return false;        }        @Override        public void onMoveEnd(MoveGestureDetector detector) {        }    }}

第三步:自定义LargeImageView

public class LargeImageView extends View {    /**图片的选择的区域 */    private BitmapRegionDecoder mDecoder;    /**图片的宽度和高度  */    private int mImageWidth, mImageHeight;    /**绘制的区域*/    private volatile Rect mRect = new Rect();    /**移动时手势*/    private MoveGestureDetector mDetector;    /**     * Creates Bitmap objects from various sources, including files, streams,     * and byte-arrays.     */    private static final BitmapFactory.Options options = new BitmapFactory.Options();    static{        /*设置让解码器以最佳方式解码*/        options.inPreferredConfig = Bitmap.Config.RGB_565;    }    public LargeImageView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    public LargeImageView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public LargeImageView(Context context) {        super(context);        init();    }    //初始化手势    private void init() {        mDetector = new MoveGestureDetector(getContext(), new SimpleMoveGestureDetector(){            @Override            public boolean onMove(MoveGestureDetector detector) {                // 移动时                int moveX = (int) detector.getMoveX();                int moveY = (int) detector.getMoveY();                Logger.i("large", "moveX == " + moveX);                Logger.i("large", "moveY == " + moveY);                //如果图片的宽度>view的宽度                if (mImageWidth > getWidth()) {                    //向左移动                    mRect.offset(-moveX, 0);                    checkWidth();                    //重构                    invalidate();                }                if (mImageHeight > getHeight()) {                    //向上移动                    mRect.offset(0, -moveY);                    checkHeight();                    //重构                    invalidate();                }                return true;            }        });    }//  private OnMoveGestureListener listener = new OnMoveGestureListener(){////      @Override//      public boolean onMoveBegin(MoveGestureDetector detector) {//          //Toast.makeText(getContext(), "开始移动", 1).show();//          return false;//      }////      @Override//      public boolean onMove(MoveGestureDetector detector) {//          // 移动时//          int moveX = (int) detector.getMoveX();//          int moveY = (int) detector.getMoveY();//          //如果图片的宽度>view的宽度//          if (mImageWidth > getWidth()) {//              //向左移动//              mRect.offset(-moveX, 0);//              checkWidth();//              //重构//              invalidate();//          }//          if (mImageHeight > getHeight()) {//              //向上移动//              mRect.offset(0, -moveY);//              checkHeight();//              //重构//              invalidate();//          }//          return true;//      }////      @Override//      public void onMoveEnd(MoveGestureDetector detector) {//          //Toast.makeText(getContext(), "移动停止", 1).show();//      }//      //  };    /**     * 把图片的宽度归位     */    protected void checkWidth() {        Rect rect = mRect;        int width = mImageWidth;        //图片的右边 > view        if (rect.right > width) {            rect.right = width;            //左边 = 图片的宽度 - 视图宽度            rect.left = width - getWidth();        }        //在屏幕外        if (rect.left < 0) {            rect.left  = 0;            //右边 = 视图宽度            rect.right = getWidth();        }    }    /**     * 图片的高度归位     */    protected void checkHeight() {        Rect rect = mRect;        int height = mImageHeight;        if (rect.bottom > height) {            rect.bottom = height;            rect.top = height - getHeight();        }        if (rect.top < 0) {            rect.top = 0;            rect.bottom = getHeight();        }    }    /**     * 第一步:加载图片后,显示图片的中心位置     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //指的是视图的测量宽度        int widthMeasure = getMeasuredWidth();        int heightMeasure = getMeasuredHeight();        //图片实际的宽度        int imageWidth = mImageWidth;        int imageHeight = mImageHeight;        //默认直接显示图片的中心区域,可以自己去调节                mRect.left = (imageWidth - widthMeasure)/2;        mRect.top = (imageHeight - heightMeasure)/2;        mRect.right = mRect.left + widthMeasure;        mRect.bottom = mRect.top + heightMeasure;        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    /**     * 第二步:把图片的事件交由手势来处理     */    @Override    public boolean onTouchEvent(MotionEvent event) {        //touchevent事件有手势来处理        mDetector.onTouchEvent(event);        return true;    }    @Override    protected void onDraw(Canvas canvas) {        Bitmap bm = mDecoder.decodeRegion(mRect, options);        //从左上角度开始画        canvas.drawBitmap(bm, 0, 0, null);        super.onDraw(canvas);    }    /**     * 向外提供加载图片后得到的输入流     * @param is     * @return     */    protected void setInputStream(InputStream is){        try {            //得到要加载显示的图片区域            mDecoder = BitmapRegionDecoder.newInstance(is, false);            BitmapFactory.Options tmpOptions = new BitmapFactory.Options();            tmpOptions.inJustDecodeBounds = true;            BitmapFactory.decodeStream(is, null, tmpOptions);            //获得图片的宽高            mImageHeight = tmpOptions.outHeight;            mImageWidth = tmpOptions.outWidth;        } catch (IOException e) {            e.printStackTrace();        } finally{            if (is != null) {                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}

第四步:实现

public class MainActivity extends Activity {    private LargeImageView mImageview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_largeimage);        mImageview = (LargeImageView) findViewById(R.id.largeImage);        loadImage();    }    /**     * 从asset文件夹里加载图片      */    private void loadImage() {        try {            InputStream is = getAssets().open("22.jpg");            mImageview.setInputStream(is);        } catch (IOException e) {            e.printStackTrace();        }    }}

activity_largeimage.xml文件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.android.view.largeimageview.LargeImageView        android:id="@+id/largeImage"        android:layout_width="match_parent"        android:layout_height="match_parent" >    com.android.view.largeimageview.LargeImageView>RelativeLayout>

—————————————————————————————————————————————————–

JAVA(SSM、SSH等)20项目视频教程,共134G

下载地址:

https://item.taobao.com/item.htm?id=558680925808

———————-课程目录——————————

第01项目:OA办公自动化项目(四套)
第02项目:CRM客户关系管理项目(两套)
第03项目:宅急送项目
第04项目:杰信商贸SSH版
第05项目:电力项目(两套)
第06项目:校内网项目
第07项目:Java邮件开发教程
第08项目:java网上在线支付实战视频
第09项目:俄罗斯方块游戏开发_视频教程
第10项目:交通灯管理系统视频教程
第11项目:银行业务调度系统视频教程
第12项目:供应链系统视频教程
第13项目:网上商城项目
第14项目:药品集中采购系统视频教程
第15项目:杰信商贸SSM版
第16项目:国家税务协同平台项目
第17项目:javaWeb聊天室
第18项目:点餐系统
第19项目:网上书店
第20项目:手机进销存系统
—————————————————————————————————————————————————–

更多相关文章

  1. Android 图片加载库Glide
  2. android 自定义图片剪裁
  3. Android——ImageButton【图片按钮】的点击事件与属性
  4. 关于LinearLayout布局中,子控件平分宽度
  5. android 选择本地图片并预览
  6. linux下eclipse构建并编译android一个简单jni项目
  7. Android 实现文件(图片)上传
  8. Android对话框图片全屏

随机推荐

  1. android ViewParent requestDisallowInte
  2. Android(安卓)数据存储与读取:文件
  3. Android(安卓)PopupWindow显示位置和显示
  4. android版本自动检测更新 版本检测 自动
  5. Android中回调接口使用实例
  6. Android(安卓)四大组件之 Activity
  7. android build kernel make menuconfig及
  8. android View.GONE 失效原因
  9. android 开发奇葩问题
  10. Android(安卓)串口数据处理