【问题标题】:ViewPager & ImageView zooming issueViewPager & ImageView 缩放问题
【发布时间】:2012-12-13 13:27:40
【问题描述】:

我正在尝试使用 ViewPager 实现图像库。此外,为了实现缩放功能,我使用了来自 github 的TouchImageView。我也尝试过使用ZoomableImageView

但是,问题是,如果我缩放图像并滚动图像,那么ViewPager 会滚动而不是图像,ViewPager 的下一个视图会被加载。

如果我缩放图像然后滚动它,则图像必须移动而不是ViewPager

ViewPager 的下一个视图只有在到达缩放图像的末尾时才需要加载。该怎么做?

我找不到那个。如果我触摸并沿对角线拖动图像,只有图像才会移动。否则 ViewPager 的拖动被调用。

ps:这不是重复的。缩放完成。但问题是在图像缩放之后。

【问题讨论】:

    标签: android android-viewpager android-imageview pinchzoom


    【解决方案1】:

    是的,我也遇到了与 TouchImageView 不同的问题。

    解决了当我的视图获得焦点时禁用 ViewPager 的问题。

    public class EnableDisableViewPager extends ViewPager {
    
        private boolean enabled = true;
    
        public EnableDisableViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent arg0) {
            if(enabled)
                return super.onInterceptTouchEvent(arg0);
    
            return false;
        }
    
        public boolean isEnabled() {
            return enabled;
        }
    
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
    

    所以在 TouchImageView 中实现你的监听器来触发一个事件,无论是缩放还是拖动。

    在您的 Activity 中为您的视图对象设置监听器。因此,当这些事件发生时,只需禁用视图寻呼机。

    注意:您还需要一个鼠标向上事件来启用 viewpager。

    已编辑

    这仅适用于缩放,因此要让 ViewPager 滑动页面,您应该缩放回原始页面。

    将这些代码添加到您的 TouchImageView

        public class TouchImageView extends ImageView {
    
            ...
        private TouchEventListener touchEventListener;
    
            private void sharedConstructing(Context context) {
                ...
    
                setOnTouchListener(new OnTouchListener() {
    
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        ...
                            case MotionEvent.ACTION_UP:
                                ...
                                if(touchEventListener != null)
                                {
                                    if(saveScale == 1.0)
                                        touchEventListener.onZoomToOriginal();
                                    else
                                        touchEventListener.onZoom();
                                }
                                break;
    
                            ...
                        }
                        ...
                    }
    
                });
            }
    
            ...
    
    public TouchEventListener getTouchEventListener() {
            return touchEventListener;
        }
    
        public void setTouchEventListener(TouchEventListener touchEventListener) {
            this.touchEventListener = touchEventListener;
        }
    
    
            public interface TouchEventListener 
            {
                void onZoom();
                void onZoomToOriginal();
            }
        }
    

    更好的解决方案

    我们可以通过使用下面给出的方法来实现这一点,而无需将 ViewPager 扩展到新的类。

    requestDisallowInterceptTouchEvent(true);
    

    有了这个,我们可以在不缩小到原始位置的情况下滑动,就像我们在图库和许多其他应用程序中看到的那样。

    public class TouchImageView extends ImageView {
    
            ...
    private void stopInterceptEvent()
    {
        getParent().requestDisallowInterceptTouchEvent(true);
    }
    
    private void startInterceptEvent()
    {
        getParent().requestDisallowInterceptTouchEvent(false);
    }
    
    private void sharedConstructing(Context context) {
        super.setClickable(true);
        this.context = context;
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
        matrix.setTranslate(1f, 1f);
        m = new float[9];
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);
    
        setOnTouchListener(new OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mScaleDetector.onTouchEvent(event);
    
                matrix.getValues(m);
                float x = m[Matrix.MTRANS_X];
                float y = m[Matrix.MTRANS_Y];
                PointF curr = new PointF(event.getX(), event.getY());
    
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        last.set(event.getX(), event.getY());
                        start.set(last);
                        mode = DRAG;
                        stopInterceptEvent();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG) {
                            float deltaX = curr.x - last.x;
                            float deltaY = curr.y - last.y;
                            float scaleWidth = Math.round(origWidth * saveScale);
                            float scaleHeight = Math.round(origHeight * saveScale);
                            if (scaleWidth < width) {
                                deltaX = 0;
                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom); 
                            } else if (scaleHeight < height) {
                                deltaY = 0;
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);
                            } else {
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);
    
                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom);
                            }
    
                            if(deltaX == 0)
                                startInterceptEvent();
                            else
                                stopInterceptEvent();
    
                            matrix.postTranslate(deltaX, deltaY);
                            last.set(curr.x, curr.y);
                        }
                        break;
    
                    case MotionEvent.ACTION_UP:
                        mode = NONE;
                        int xDiff = (int) Math.abs(curr.x - start.x);
                        int yDiff = (int) Math.abs(curr.y - start.y);
                        if (xDiff < CLICK && yDiff < CLICK)
                            performClick();
                        startInterceptEvent();
                        break;
    
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        break;
                }
                setImageMatrix(matrix);
                invalidate();
                return true; // indicate event was handled
            }
    
        });
    }
    }
    

    【讨论】:

    • 请修改 TouchImageView。我真的很努力。我无法找到解决方案。如果您能在这方面帮助我,那将非常有帮助!请使用修改后的 TouchImageView 更新您的答案。
    • 谢谢!你拯救了我的一天!
    • 什么是变量宽度、高度、右侧、底部?没提过。
    • @VivekKhandelwal 非常感谢你,但图像的边缘有时仍被另一张图像剪切;再加上我的图像正在填充它的父级,现在它变小了,为什么?谢谢。
    • 谢谢 Vivek 这对我有用,节省了很多时间,再次感谢!
    【解决方案2】:

    我通过添加以下代码让它工作:

    if(deltaX == 0 &&  saveScale == 1.0 )
        startInterceptEvent();
    else
        stopInterceptEvent();
    

    【讨论】:

      【解决方案3】:

      我终于找到了Subsampling Scale Image View 库,它甚至可以与 Android 支持包中的标准 ViewPager 一起使用,无需任何自定义。

      【讨论】:

        【解决方案4】:
        if(deltaX == 0 || saveScale == 1.0 )
            startInterceptEvent();
        else
            stopInterceptEvent();
        

        【讨论】:

          【解决方案5】:

          如果有人有水平浏览器,重要的是更改@kirit-vaghela 代码:

          if(deltaX == 0 || saveScale == 1.0 )
              startInterceptEvent();
          else
              stopInterceptEvent();
          

          if(saveScale == 1.0 )
              startInterceptEvent();
          else
              stopInterceptEvent();
          

          所以适配器只有在 1.0 时才会改变图片

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-03-05
            • 1970-01-01
            • 1970-01-01
            • 2021-12-22
            • 1970-01-01
            • 2017-07-02
            • 2012-09-20
            相关资源
            最近更新 更多