【问题标题】:ScaleGestureDetector doesnot work over recyclerviewScaleGestureDetector 在 recyclerview 上不起作用
【发布时间】:2020-04-05 00:08:52
【问题描述】:

我有一个项目需要使用ScaleGestureDetector 缩放RecyclerView。它适用于在RecyclerView 之外进行捏合缩放,但不适用于在RecyclerView 上进行捏合。我一直在努力解决这个问题,但无法解决它。非常感谢任何帮助。提前致谢!!

这是我的java代码

recyclerView.addOnItemTouchListener(new GalleryAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new GalleryAdapter.ClickListener() {
            @Override
            public void onClick(View view, int position) {
                Bundle bundle = new Bundle();
                bundle.putSerializable("images", images);
                bundle.putInt("position", position);

                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
                newFragment.setArguments(bundle);
                newFragment.show(ft, "slideshow");
            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));

scaleGestureDetector = new ScaleGestureDetector(
                this, new MySimpleOnScaleGestureListener(textMsg, recyclerView, factor));

private class MySimpleOnScaleGestureListener
            extends ScaleGestureDetector.SimpleOnScaleGestureListener{

        TextView viewMessage;
        RecyclerView viewMyImage;

        float factor;

        public MySimpleOnScaleGestureListener(TextView v, RecyclerView iv ,float f) {
            super();
            viewMessage = v;
            viewMyImage = iv;
            factor = f;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            //factor = 10.0f;
            return true;
            //return super.onScaleBegin(detector);
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float scaleFactor = detector.getScaleFactor() - 1;
            factor += scaleFactor;
            viewMessage.setText(String.valueOf(scaleFactor)
                    + "\n" + String.valueOf(factor));
            viewMyImage.setScaleX(factor);
            viewMyImage.setScaleY(factor);
            return true;
            //return super.onScale(detector);
        }
    }

【问题讨论】:

    标签: android android-recyclerview pinchzoom


    【解决方案1】:

    Recycleview 使用此类放大和缩小。

    import android.content.Context;
    import android.graphics.Canvas;
    import android.support.annotation.NonNull;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    
    
    public class PinchRecyclerView extends RecyclerView {
        private static final int INVALID_POINTER_ID = -1;
        private int mActivePointerId = INVALID_POINTER_ID;
        private ScaleGestureDetector mScaleDetector;
        private float mScaleFactor = 1.f;
        private float maxWidth = 0.0f;
        private float maxHeight = 0.0f;
        private float mLastTouchX;
        private float mLastTouchY;
        private float mPosX;
        private float mPosY;
        private float width;
        private float height;
    
    
        public PinchRecyclerView(Context context) {
            super(context);
            if (!isInEditMode())
                mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        public PinchRecyclerView(Context context, AttributeSet attrs) {
            super(context, attrs);
            if (!isInEditMode())
                mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        public PinchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            if (!isInEditMode())
                mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            width = MeasureSpec.getSize(widthMeasureSpec);
            height = MeasureSpec.getSize(heightMeasureSpec);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            try {
                return super.onInterceptTouchEvent(ev);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    
        @Override
        public boolean onTouchEvent(@NonNull MotionEvent ev) {
            super.onTouchEvent(ev);
            final int action = ev.getAction();
            mScaleDetector.onTouchEvent(ev);
            switch (action & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: {
                    final float x = ev.getX();
                    final float y = ev.getY();
                    mLastTouchX = x;
                    mLastTouchY = y;
                    mActivePointerId = ev.getPointerId(0);
                    break;
                }
    
                case MotionEvent.ACTION_MOVE: {
    
                    final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
                            >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                    final float x = ev.getX(pointerIndex);
                    final float y = ev.getY(pointerIndex);
                    final float dx = x - mLastTouchX;
                    final float dy = y - mLastTouchY;
    
                    mPosX += dx;
                    mPosY += dy;
    
                    if (mPosX > 0.0f)
                        mPosX = 0.0f;
                    else if (mPosX < maxWidth)
                        mPosX = maxWidth;
    
                    if (mPosY > 0.0f)
                        mPosY = 0.0f;
                    else if (mPosY < maxHeight)
                        mPosY = maxHeight;
    
                    mLastTouchX = x;
                    mLastTouchY = y;
    
                    invalidate();
                    break;
                }
    
                case MotionEvent.ACTION_UP: {
                    mActivePointerId = INVALID_POINTER_ID;
                    break;
                }
    
                case MotionEvent.ACTION_CANCEL: {
                    mActivePointerId = INVALID_POINTER_ID;
                    break;
                }
    
                case MotionEvent.ACTION_POINTER_UP: {
                    final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                    final int pointerId = ev.getPointerId(pointerIndex);
                    if (pointerId == mActivePointerId) {
                        final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                        mLastTouchX = ev.getX(newPointerIndex);
                        mLastTouchY = ev.getY(newPointerIndex);
                        mActivePointerId = ev.getPointerId(newPointerIndex);
                    }
                    break;
                }
            }
    
            return true;
        }
    
        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.translate(mPosX, mPosY);
            canvas.scale(mScaleFactor, mScaleFactor);
            canvas.restore();
        }
    
        @Override
        protected void dispatchDraw(@NonNull Canvas canvas) {
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            if (mScaleFactor == 1.0f) {
                mPosX = 0.0f;
                mPosY = 0.0f;
            }
            canvas.translate(mPosX, mPosY);
            canvas.scale(mScaleFactor, mScaleFactor);
            super.dispatchDraw(canvas);
            canvas.restore();
            invalidate();
        }
    
        private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                mScaleFactor *= detector.getScaleFactor();
                mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 3.0f));
                maxWidth = width - (width * mScaleFactor);
                maxHeight = height - (height * mScaleFactor);
                invalidate();
                return true;
            }
        }
    }
    

    希望对你有帮助!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      相关资源
      最近更新 更多