美文网首页android故事累积
Fresco结合PhotoView实现手势缩放

Fresco结合PhotoView实现手势缩放

作者: 盛夏的阳光 | 来源:发表于2016-05-25 17:05 被阅读3999次

    项目中需要用到手势缩放,所以查找了一些Demo,特作此笔记。
    (第一次写正式的笔记,文笔不佳,请见谅(~ ̄▽ ̄)~)
    笔者查看到的几个项目,都是使用自定义控件,一个是ImagePipeline结合PhotoView,一个是使用SimpleDraweeView结合PhotoView,因此下文主要介绍这两种方法。

    1. ImagePipeline结合PhotoView

    • 自定义PhotoView继承ImageView:如PhotoView.java
      显示图片的主要代码块:
      public void setImageUri(Uri uri) {

      ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).build();
      ImagePipeline imagePipeline = Fresco.getImagePipeline();
      final DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this);
      DraweeController controller = Fresco.newDraweeControllerBuilder()
              .setOldController(mDraweeHolder.getController())
              .setImageRequest(imageRequest)
              .setControllerListener(new BaseControllerListener<ImageInfo>() {
                  @Override
                  public void onFinalImageSet(String s, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) {
                      try {
                          // Do something with the image, but do not keep the reference to it! 
                          // The image may get recycled as soon as the reference gets closed below. 
                          // If you need to keep a reference to the image, read the following sections.
                          imageReference = dataSource.getResult();
                          if (imageReference != null) {
                              CloseableImage image = imageReference.get();
                              if (image != null && image instanceof CloseableStaticBitmap) {
                                  CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image;
                                  Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap();
                                  if (bitmap != null) {
                                      //这里可以对bitmap进行操作
                                      setImageBitmap(bitmap);
                                  }
                              }
                          }
                      } finally {
                          dataSource.close();
                          CloseableReference.closeSafely(imageReference);
                      }
                  }
              })
              .setTapToRetryEnabled(true)
              .build();
      mDraweeHolder.setController(controller);}
      

    这样就实现了手势缩放。
    参考

    2. SimpleDraweeView结合PhotoView

    • 自定义PhotoDraweeView继承SimpleDraweeView,实现IAttacher接口
    • 在xml中
      <me.relex.photodraweeview.PhotoDraweeView
      android:id="@+id/photo_drawee_view"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"/>
    • 在Activity中
      PipelineDraweeControllerBuilder controller = Fresco.newDraweeControllerBuilder();
      controller.setUri(Uri.parse("res:///" + R.drawable.panda));
      controller.setOldController(mPhotoDraweeView.getController());
      // You need setControllerListener
      controller.setControllerListener(new BaseControllerListener<ImageInfo>() {
      @Override
      public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
      super.onFinalImageSet(id, imageInfo, animatable);
      if (imageInfo == null || mPhotoDraweeView == null) {
      return;
      }
      mPhotoDraweeView.update(imageInfo.getWidth(), imageInfo.getHeight());
      }
      });
      mPhotoDraweeView.setController(controller.build());

    这样就实现了SimpleDraweeView的手势缩放。
    参考Demo:
    PhotoDraweeView

    3.修改图片,实现缩放

    由于笔者项目中需要实现的是,一张图片上添加另一张小图片,再实现缩放,见如下效果:

    QQ截图20160525163243.png
    需要修改Demo中的代码,Fresco的文档中写到修改图片的方法如下:
    Modifying the Image (Postprocessing) QQ截图20160525163645.png
    主要修改图片的操作在process()方法中
    因此,修改上述两种方法中的图片:
    1. ImagePipeline
    • 在自定义的PhotoView类中:
      找到上面让图片显示的代码,添加:
    QQ截图20160525164356.png
    但是在部分机型上会报IllegalStateException错误,解决办法:
    bitmap=bitmap.copy(Config.ARGB_4444, true);
    不过这样的话,图片占用内存又增大了,Google一下,有一种解决方法是直接在JNI操作,但是我自己没有仔细研究AndroidJniBitmapOperations

    2.SimpleDraweeView

    • 自定义的控件无需更改,直接在Activity中修改:
      mPhotoDraweeView = (PhotoDraweeView) findViewById(R.id.photo_drawee_view);
      Postprocessor redMeshPostprocessor = new BasePostprocessor() {
      @Override
      public String getName() {
      return "redMeshPostprocessor";
      }
      @Override
      public void process(Bitmap bitmap) {
      Bitmap blueBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_blue);
      Bitmap redBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_red);
      Bitmap adBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_star);
      Canvas canvas = new Canvas(bitmap);
      canvas.drawBitmap(blueBitmap, 50, 50, null);
      canvas.drawBitmap(redBitmap, 200,200, null);
      canvas.drawBitmap(adBitmap, 300, 300, null);
      }
      };
    QQ截图20160525165701.png

    其余代码不变。这样就完成了 修改图片+手势缩放。用这种方法,即使在第一种方法中报IllegalStateException错的2.3.7机型,也没有报错。

    题外话
    写了几个小时,终于把这篇篇幅不长的文章磕磕绊绊写完了y(๑•̀ㅂ•́)و✧

    QQ图片20160525170247.png
    手生,还是得多写多记录,看花容易画花难呀~( ̄▽ ̄~)(~ ̄▽ ̄)~

    相关文章

      网友评论

        本文标题:Fresco结合PhotoView实现手势缩放

        本文链接:https://www.haomeiwen.com/subject/xajtdttx.html