ViewPager和ImageView缩放问题

12
我尝试使用ViewPager实现图像库。此外,为了实现缩放功能,我正在使用github上的TouchImageView。我还尝试使用ZoomableImageView。但是问题是,如果我缩放图像并滚动图像,则ViewPager会滚动并加载下一个视图而不是图像。如果我缩放图像,然后滚动它,那么图像必须移动而不是ViewPager。只有当缩放后的图像到达结尾时,ViewPager的下一个视图才会被加载。如何做到这一点?我找不到方法。只有在对图像进行对角线触摸和拖动时,图像才会移动。否则将调用ViewPager的拖动。注意:这不是重复内容。缩放已完成。但问题出现在图像缩放后。
5个回答

22

我也遇到了同样的问题,不过不是出现在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中实现您的监听器,以触发缩放或拖动事件。

在活动中将监听器设置为您的视图对象。因此,当这些事件发生时,只需禁用ViewPager。

注意:您还需要一个鼠标抬起事件来启用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
        }

    });
}
}

这些变量 width、height、right、bottom 是什么?没有提到。 - Gangnaminmo Ako
@VivekKhandelwal 非常感谢您,但是图像有时仍会被其他图像切割边缘;此外,我的图像以前填充其父级,现在变小了,为什么?谢谢。 - Learning Android
谢谢Vivek,这个对我很有用,节省了很多时间,再次感谢! - Anil Deshmukh
@VivekKhandelwal 什么是宽度、高度、右侧和底部? - Nitesh Kumar
非常感谢你,你救了我的一天 :) - Tuan Chau
显示剩余3条评论

1
我通过添加以下代码使它起作用:

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

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

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

0
如果有人使用水平的ViewPager,那么改变@kirit-vaghela的代码是很重要的。
if(deltaX == 0 || saveScale == 1.0 )
    startInterceptEvent();
else
    stopInterceptEvent();

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

所以适配器只会在版本为1.0时更改图片


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接