使用Universal Image Loader和View Pager时出现的图像缩放问题

6

我想在ImagePagerActivity中使用Universal Image Loader和ImageViewZoom。

我能够缩放图片,可以滑动到下一张图片。但是当图片处于缩放状态时,我遇到了问题。

enter image description here

如果一张图片被缩放,我想要看到同一图片的右侧部分并向左滑动它,它会转到下一张图片。请在这方面帮助我。

以下是我的XML代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="1dip" >

  <it.sephiroth.android.library.imagezoom.ImageViewTouch
     android:layout_weight="1"
     android:id="@+id/image"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:scaleType="fitCenter" />

  <ProgressBar
    android:id="@+id/loading"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:visibility="gone" />

</FrameLayout>

编辑:

感谢NOSTRA,现在我能够使用以下代码控制缩放和滑动。但是多点触控缩放存在问题,我无法使用两个手指进行缩放。

这是我的先前的代码(与两个手指一起工作得很好):

public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {


        @Override
        public boolean onScale( ScaleGestureDetector detector ) {
            Log.d( LOG_TAG, "onScale" );
            float span = detector.getCurrentSpan() - detector.getPreviousSpan();
            float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
            if ( mScaleEnabled ) {
                targetScale = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-0.1f ) );
                zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
                mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-1.0f ) );
                mDoubleTapDirection = 1;
                invalidate();
                return true;
            }
            return false;
        }
    }

这是修改后的版本:

public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            externalScaleListener.onScaleBegin();
                return super.onScaleBegin(detector);
        }
        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            externalScaleListener.onScaleEnd(mCurrentScaleFactor);
        }
    }

嗨,我也在寻找同样的解决方法。你解决了这个问题吗?当我尝试在ViewPager Activity中使用ImageViewTouch加载图像时,我无法看到图像。 - sam_k
请帮助我解决我的问题。 - sam_k
@Sam_k,以下代码完美运行... - wolverine
你用Universal Image Loader Page activity和ImageViewTouch做过这件事吗?我也打算这么做.. 我是对的吧? - sam_k
@wolverine,所以使用下面的代码后,缩放时查看图像周围的问题解决了吗?还是你实现了手势-imageview? 我似乎无法让它工作。我很高兴得到一些帮助。首先,您需要修改Imageviewtouch并构建一个新文件放入libs中。然后,您创建DeactivableViewPager.java文件吗?然后将其实现到“Imagepageractivity”中?我只是似乎无法让它工作。 - Joe
显示剩余6条评论
2个回答

8

首先,您必须能够监听图像的缩放。ImageViewTouch不支持此功能(例如,gesture-imageview支持它),因此您应该自己实现它。

请按照以下方式更改ImageViewTouch.java

public class ImageViewTouch extends ImageViewTouchBase {

    ...

    private OnPageScaleListener externalScaleListener;

    public void setOnScaleListener(OnPageScaleListener onScaleListener) {
        this.externalScaleListener = onScaleListener;
    }

    public interface OnPageScaleListener {
        void onScaleBegin();

        void onScaleEnd(float scale);
    }

    @Override
    protected void onZoom(float scale) {
        super.onZoom(scale);
        if (!mScaleDetector.isInProgress()) {
            mCurrentScaleFactor = scale;
            externalScaleListener.onScaleEnd(scale);
        }
    }

    public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            externalScaleListener.onScaleBegin();
                return super.onScaleBegin(detector);
        }

        ...

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            externalScaleListener.onScaleEnd(mCurrentScaleFactor);
        }
    }

    ...
}

然后在你的应用程序中使用下一个实现ViewPager

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * {@link ViewPager} which can be deactivated (ignore touch events)
 * 
 * @author Sergey Tarasevich
 * @created 19.07.2012
 */
public class DeactivableViewPager extends ViewPager {

    private boolean activated = true;

    public DeactivableViewPager(Context context) {
        super(context);
    }

    public DeactivableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void activate() {
        activated = true;
    }

    public void deactivate() {
        activated = false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (activated) {
            try {
                return super.onInterceptTouchEvent(event);
            } catch (Exception e) { // sometimes happens
                return true;
            }
        } else {
        return false;
    }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        try {
            return super.onTouchEvent(event);
        } catch (Exception e) {
            return true;
        }
    }
}

然后在您的ViewPager适配器中,您应该为ImageViewTouch设置下一个缩放监听器:

ImageViewTouch imageView = ...;
imageView.setOnScaleListener(new OnPageScaleListener() {
    @Override
    public void onScaleBegin() {
        viewPager.deactivate();
    }

    @Override
    public void onScaleEnd(float scale) {
        if (scale > 1.0) {
            viewPager.deactivate();
        } else {
            viewPager.activate();
        }
    }
});

imageLoader.displayImage(url, imageView, ...);

同时不要忘记在ImageLoader的配置中为maxImage***ForMemoryCache设置较大的值,这样UIL在解码为位图时就不会降低原始图片的尺寸:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
        ...
        .memoryCacheExtraOptions(3000, 3000)
        ...
        .build();

嗨,我也使用了gesture-imageview,但是我仍然遇到了同样的问题。 - wolverine
我能够使用上述代码控制图像的缩放和滑动,但我只能通过双击来进行缩放。我想要使用两个手指也能实现缩放功能。我该如何做呢?请查看我的编辑。 - wolverine
你不应该替换ScaleListener,而是应该添加onScaleBegin()onScaleEnd()方法。还有第三个方法... - nostra13
@NOSTRA 在UIL中添加了这个DeactivableViewPager类后,接下来我该怎么做?我需要扩展这个类而不是PageAdapter吗? - sam_k
@Sam_k 不,您仍然扩展PagerAdapter,但是您将ViewPager实例变量的类型更改为DeactivableViewPager,并且在ImagePagerAdapter instantiateItem方法中,您将该行更改为ImageViewTouch imageView = (ImageViewTouch) imageLayout.findViewById(R.id.pager_image); - brendan
@NOSTRA 我添加了你的代码,这使我能够成功地缩放,但是有时候分页器活动不允许我转到下一张图片。如果我通过缩放图像来重新调整图像大小,那么我就能够转到下一张图片。我在onScale中加入了打印语句,看起来当比例大于1时会出现这个问题。你知道可能是什么原因导致这个问题吗? - brendan

0

我在viewPager中遇到了预缩放图像的问题,但现在已经解决了。

你需要在ImageViewTouchBase类中搜索这一行:

protected DisplayType mScaleType = DisplayType.NONE;

然后将其更改为:

protected DisplayType mScaleType = DisplayType.FIT_TO_SCREEN;

默认情况下,DisplayType设置为NONE,很简单,只需使用FIT_TO_SCREEN,您的图像在viewPager中滑动时将保持默认大小。

干杯


您可以设置这些属性,使图像始终适合屏幕

<it.sephiroth.android.library.imagezoom.ImageViewTouch
    android:id="@+id/iv_pager_image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:adjustViewBounds="true"
    android:contentDescription="@string/descr_image"
    android:scaleType="matrix" />

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