iielse / imageviewer

A simple and customizable Android full-screen image viewer 一个简单且可自定义的Android全屏图像浏览器
MIT License
2.23k stars 310 forks source link

如果不用Glide,用Fresco呢 #50

Closed lofty14 closed 6 years ago

lofty14 commented 6 years ago

有个问题是fresco我们用的是自定义的imageview集成自SimpleDraweeView,不像glide可以直接load到imageview

iielse commented 6 years ago

ImageWatcher构造需要传入一个图片下载引擎,至于用什么方法下载都无所谓的。

public interface Loader {
        void load(Context context, Uri uri, LoadCallback lc);
}
public interface LoadCallback {
        void onResourceReady(Drawable var1);

        void onLoadStarted(Drawable var1);

        void onLoadFailed(Drawable var1);
}

fresco 框架 https://blog.csdn.net/android_farmer/article/details/51253589

Android-Universal-Image-Loader框架 https://github.com/nostra13/Android-Universal-Image-Loader

volley框架 https://blog.csdn.net/guolin_blog/article/details/17482165

picasso框架 和glide差不多吧

参考代码 https://github.com/iielse/ImageWatcher/blob/master/app/src/main/java/ch/ielse/demo/p02/SimpleLoader.java

tip ImageWatcher 源码中 onLoadStartedonLoadFailed 入参的 drawable对象没有被使用到,所以可以传null。 如果你使用的框架中没有 onLoadStarted 回调,可以自己在加载的时刻手动触发。

lofty14 commented 6 years ago

我刚刚试了用fresco替换glide,修改了这个SimpleLoader,但是报错了,点开图片只显示小图,logcat里面看到报错的信息。 我尝试把报错的部分用runOnUIThread放到主线程处理,发现还是有问题 ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(true).build(); ImagePipeline imagePipeline = Fresco.getImagePipeline(); DataSource<CloseableReference> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); dataSource.subscribe(new BaseBitmapDataSubscriber() { @Override protected void onNewResultImpl(Bitmap bitmap) { lc.onResourceReady(new BitmapDrawable(bitmap)); }

    @Override
    protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
      lc.onLoadFailed(null);
    }
  }, CallerThreadExecutor.getInstance());

  GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(context.getResources())
      .setFadeDuration(300)
      .setProgressBarImage(new ProgressBarDrawable())
      .build();
  DraweeHolder<GenericDraweeHierarchy> draweeHolder = DraweeHolder.create(hierarchy, context);
  PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
      .setOldController(draweeHolder.getController())
      .setImageRequest(imageRequest)
      .build();
  controller.onClick();

0 11:54:01.885 26768-26917/ch.ielse.demo.p02 E/unknown:: unhandled exception android.util.AndroidRuntimeException: Animators may only be run on Looper threads at android.animation.ValueAnimator.start(ValueAnimator.java:1011) at android.animation.ValueAnimator.start(ValueAnimator.java:1065) at android.view.ViewPropertyAnimator.startAnimation(ViewPropertyAnimator.java:904) at android.view.ViewPropertyAnimator.start(ViewPropertyAnimator.java:416) at com.github.ielse.imagewatcher.ImageWatcher$ImagePagerAdapter$1.onResourceReady(ImageWatcher.java:1019) at ch.ielse.demo.p02.SimpleLoader$1.onNewResultImpl(SimpleLoader.java:56)

iielse commented 6 years ago

Activity.onCreate()

Fresco.initialize(this);
iwHelper = ImageWatcherHelper.with(this, new FrescoSimpleLoader());
class FrescoSimpleLoader implements ImageWatcher.Loader {
    @Override
    public void load(final Context context, Uri uri, final ImageWatcher.LoadCallback lc) {
        lc.onLoadStarted(null);

        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(true).build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this);
        dataSource.subscribe(new BaseBitmapDataSubscriber() {
            @Override
            public void onNewResultImpl(@Nullable final Bitmap bitmap) {
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        lc.onResourceReady(new BitmapDrawable(bitmap));
                    }
                });
            }

            @Override
            public void onFailureImpl(DataSource dataSource) {
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        lc.onLoadFailed(null);
                    }
                });
            }
        }, CallerThreadExecutor.getInstance());
    }
}

我自己刚才试了的,fresco 这样写没有问题。 ((Activity) context).runOnUiThread(new Runnable() { 这个写法可以优化,大家加油

iielse commented 6 years ago

context 弱引用,联动生命周期什么的

iielse commented 6 years ago

fresco的代码已经提交了。 https://github.com/iielse/ImageWatcher/blob/master/app/src/main/java/ch/ielse/demo/p02/FrescoSimpleLoader.java

@lofty14 你确认下有问题没。

lofty14 commented 6 years ago

妥了