美文网首页
自定义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