美文网首页
自定义View 仿脉脉职言中图片效果02

自定义View 仿脉脉职言中图片效果02

作者: 花椒人生 | 来源:发表于2018-12-28 15:09 被阅读0次

1.效果

maimai.gif

2.根据效果分析

这里脉脉APP上的图片效果有
1.双击放大
2.单手指滑动图片
3.图片惯性滑动
4.双指滑动放大缩小

3.代码实现

1.添加图片,将图片正常显示
image.png
    public class CMMaiMaiImageView extends View {
    
        private static final float IMAGE_WIDTH = DpToPxUtil.dp2px(100);
    
        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private Bitmap mBitmap;
    
    
        private float originOffsetX;
        private float originOffsetY;
    
        private float smallScalab;
        private float bigScalab;
    
        public CMMaiMaiImageView(Context context) {
            this(context,null);
        }
    
        public CMMaiMaiImageView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public CMMaiMaiImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            //添加绘制图片
            mBitmap = CMBitMapUtils.getAvatarWithImage(getResources(),(int) IMAGE_WIDTH, R.drawable.kenan);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
    
            originOffsetX = ((float)(getWidth() - mBitmap.getWidth())) / 2f;
            originOffsetY = ((float)(getHeight() - mBitmap.getHeight())) / 2f;
    
            if( ((float)mBitmap.getWidth()/mBitmap.getHeight()) > ((float) mBitmap.getHeight()/mBitmap.getWidth())){
                //图片宽度比高度大,横向图片
                smallScalab = (float) getWidth()/mBitmap.getWidth();
                bigScalab = (float) getHeight()/mBitmap.getHeight();
            }else{
                //图片宽度比高度小,纵向图片
                smallScalab = (float) getHeight()/mBitmap.getHeight();
                bigScalab = (float) getWidth()/mBitmap.getWidth();
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            canvas.scale(smallScalab,smallScalab,getWidth()/2f,getHeight()/2f);
            canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return super.onTouchEvent(event);
        }
    }
2.添加图片双击放大缩小效果
    //判断当前图片展示的是大图还是小图
        private boolean isBig;
    
    
         @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            float scale = isBig ? bigScalab : smallScalab;
            canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
            canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
        }
       
    class CMGestureDetectorListener extends GestureDetector.SimpleOnGestureListener{
    
            @Override
            public boolean onDown(MotionEvent e) {
                Log.e("====","onDow=");
                return true;
            }
    
            @Override
            public void onShowPress(MotionEvent e) {
                Log.e("====","onShowPress=");
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                Log.e("====","onSingleTapUp=");
                return false;
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.e("====","onScroll=");
                return false;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
                Log.e("====","onLongPress=");
    
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.e("====","onFling=");
                return false;
            }
    
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.e("====","onSingleTapConfirmed=");
                return false;
            }
    
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.e("====","onDoubleTap=");
                isBig = !isBig;
                invalidate();
                return false;
            }
    
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.e("====","onDoubleTapEvent=" + isBig);
                return false;
            }
    
}
3.添加图片放大缩小的动画
    //图片放大缩小的动画
        private float scaleFraction;
    
        //图片放大缩小的动画
        private ObjectAnimator mObjectAnimator;
    
        public ObjectAnimator getObjectAnimator() {
            if(mObjectAnimator == null){
                mObjectAnimator = ObjectAnimator.ofFloat(this,"scaleFraction",0,1);
            }
            return mObjectAnimator;
        }
    
        public float getScaleFraction() {
            return scaleFraction;
        }
    
        public void setScaleFraction(float scaleFraction) {
            this.scaleFraction = scaleFraction;
            invalidate();
        }

双击手势中的处理

    @Override
        public boolean onDoubleTap(MotionEvent e) {
                Log.e("====","onDoubleTap=");
                isBig = !isBig;
                if(isBig){
                    getObjectAnimator().start();
                }else{
                    getObjectAnimator().reverse();
                }
                return false;
            }

绘制中的处理

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            float scale = smallScalab + (bigScalab - smallScalab)*scaleFraction;
            canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
            canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
        }
4.图片放大后的滑动处理以及边界修正

这里图片放大后,需要实现可以将图片平移

            @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            canvas.translate(offsetX,offsetY);
            float scale = smallScalab + (bigScalab - smallScalab)*scaleFraction;
            canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
            canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
        }

图片放大后位置修正

    @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.e("====","onScroll=");
                if(isBig){
                    offsetX -= distanceX;
                    offsetY -= distanceY;
    
                    offsetX = Math.min(offsetX,(mBitmap.getWidth()*bigScalab - getWidth())/2);
                    offsetX = Math.max(offsetX,-(mBitmap.getWidth()*bigScalab - getWidth())/2);
    
                    offsetY = Math.min(offsetY,(mBitmap.getHeight()*bigScalab - getHeight())/2);
                    offsetY = Math.max(offsetY,-(mBitmap.getHeight()*bigScalab - getHeight())/2);
    
                    invalidate();
                }
                return false;
            }
5.惯性滑动 OverScroller
    @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                if(isBig){
                    offsetX -= distanceX;
                    offsetY -= distanceY;
    
                    fixOffset();
    
                    invalidate();
                }
                return false;
            }
    
        private void fixOffset() {
            offsetX = Math.min(offsetX,(mBitmap.getWidth()*bigScalab - getWidth())/2);
            offsetX = Math.max(offsetX,-(mBitmap.getWidth()*bigScalab - getWidth())/2);
    
            offsetY = Math.min(offsetY,(mBitmap.getHeight()*bigScalab - getHeight())/2);
            offsetY = Math.max(offsetY,-(mBitmap.getHeight()*bigScalab - getHeight())/2);
        }
6.双指放大缩小
    class CMOnScaleListener implements ScaleGestureDetector.OnScaleGestureListener{
            float initiaScale;
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                currentFraction = initiaScale * detector.getScaleFactor() < smallScalab ? smallScalab:initiaScale * detector.getScaleFactor();
                currentFraction = currentFraction > bigScalab ? bigScalab : currentFraction;
                invalidate();
                return false;
            }
    
            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                initiaScale = currentFraction;
                return true;
            }
    
            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
    
            }
}

7 完工效果


kenan.gif

相关文章

网友评论

      本文标题:自定义View 仿脉脉职言中图片效果02

      本文链接:https://www.haomeiwen.com/subject/cvtklqtx.html