使用 fresco 实现 Android 图片手势缩放功能

2,442 阅读3分钟

前言

fresco是一款十分强大的图片加载框架,但是该框架本身不支持图片的手势放大和缩小的功能。在facebook官方的github上,facebook官方给出了具体的解决方案,但是官方的demo十分难跑起来,并且官方demo中的功能较为繁杂,理解和使用都有一定的困难。所以我做了一个测试demo出来供大家交流学习。

开发准备

在开发前,需要在项目中引入fresco,引入方法是在Module的build.gradle文件的dependencies中添加一句代码

	
compile 'com.facebook.fresco:fresco:0.12.0'

即可。

集成Samples包

Samples是fresco官方demo中的一个拓展包,包的目录如下图:

samples

在该包中,和手势缩放相关的包有两个,分别为:gestures和zoomable。gestures包的主要功能的检测手势,zoomable包的主要功能是提供一个支持手势缩放的draweeView。因为在项目中只用到手势缩放的view,所以我只导入了这两个包。

导入方法很简单,只需要把Samples复制到工程目录下就可以。

配置环境

导入完毕后还需要执行下面几步才能正常使用

  1. 修改gradle.properties文件

    在工程目录的gradle.properties文件中添加

# Deps for gradle
BUILD\_TOOLS\_VERSION=23.0.2
COMPILE\_SDK\_VERSION=23
# Deps for libraries
JUNIT\_VERSION=4.12
MOCKITO\_CORE\_VERSION=1.10.19
ROBOLECTRIC\_VERSION=3.0
NINEOLDANDROID\_VERSION=2.4.0
SUPPORT\_LIB\_VERSION=23.2.1
JSR\_305\_VERSION=3.0.0
  1. 修改settings.gradle

    在工程目录的settings.gradle文件中添加

    include ':samples:gestures'
    include ':samples:zoomable'
  2. 在项目的Build.gradle中添加

    project.ext {
    buildToolsVersion = "${BUILD_TOOLS_VERSION}"
    compileSdkVersion = COMPILE_SDK_VERSION.toInteger()
    }

做完以上两个步骤后,就能正常使用支持图片缩放的ZoomalbeDraweeView了。

使用教程

查看单个图片

  1. 新建一个activity_zoomable.xml布局文件

    
    
    	
     
    

  2. ZoomableActivity.java文件

public class ZoomableActivity extends Activity {
	private ZoomableDraweeView draweeView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    FLog.setMinimumLoggingLevel(FLog.VERBOSE);
	    Set listeners = new HashSet<>();
	    listeners.add(new RequestLoggingListener());
	    ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
	            .setRequestListeners(listeners)
	            .setBitmapsConfig(Bitmap.Config.ARGB_8888)
	            .build();
	    Fresco.initialize(this, config);
	    setContentView(R.layout.activity_zoomable);
	
	
	    DraweeController controller = Fresco.newDraweeControllerBuilder()
	            .setUri("http://pic13.nipic.com/20110326/2457331_232645672000_2.jpg")
	            .build();
	    draweeView = (ZoomableDraweeView) findViewById(R.id.zoomableView);
	    draweeView.setController(controller);
	
	
	
	}
}

使用的方法和SimpleDraweeView差不多,不同的地方是Fresco初始化的时候需要传入ImagePipelineConfig对象,并且ZoomableDraweeView不知直接设置图片的uri,而是需要通过DraweeController对象来设置。

通过上面的代码,已经能够完成图片的加载和图片的放大缩小操作。但是实际开发的时候往往需要显示一组图片,所以下面来介绍下如何使用ZoomableDraweeView展示一组图片,并支持手势放大缩小功能。

显示多个图片

  1. 新建一个activity_zoomable_list.xml文件

    
     
    	
         
             
         
    	
         
             
         
    	
         
             
         
    	
     
    

  2. ZoomableListActivity.java文件

    public class ZoomableListActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         FLog.setMinimumLoggingLevel(FLog.VERBOSE);
         Set listeners = new HashSet<>();
         listeners.add(new RequestLoggingListener());
         ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
                 .setRequestListeners(listeners)
                 .setBitmapsConfig(Bitmap.Config.ARGB_8888)
                 .build();
         Fresco.initialize(this, config);
         setContentView(R.layout.activity_zoomable_list);
    	
         MyPagerAdapter adapter = new MyPagerAdapter();
         ViewPager pager = (ViewPager) findViewById(R.id.pager);
         pager.setAdapter(adapter);
     }
    }
  3. MyPagerAdapter.java文件

    public class MyPagerAdapter extends PagerAdapter{
     public Object instantiateItem(ViewGroup container, int position) {
         FrameLayout page = (FrameLayout) container.getChildAt(position);
         ZoomableDraweeView zoomableDraweeView = (ZoomableDraweeView) page.getChildAt(0);
         DraweeController controller = Fresco.newDraweeControllerBuilder()
                 .setUri("http://pic25.nipic.com/20121112/5955207_224247025000_2.jpg")
                 .build();
         zoomableDraweeView.setController(controller);
         zoomableDraweeView.setTapListener(createTapListener(position));
         page.requestLayout();
         return page;
     }
    	
     public void destroyItem(ViewGroup container, int position, Object object) {
         FrameLayout page = (FrameLayout) container.getChildAt(position);
         ZoomableDraweeView zoomableDraweeView = (ZoomableDraweeView) page.getChildAt(0);
         zoomableDraweeView.setController(null);
     }
    	
     @Override
     public int getCount() {
         return 3;
     }
    	
     @Override
     public boolean isViewFromObject(View arg0, Object arg1) {
         return arg0 == arg1;
     }
    	
     private GestureDetector.SimpleOnGestureListener createTapListener(final int position) {
         return new GestureDetector.SimpleOnGestureListener() {
             @Override
             public void onLongPress(MotionEvent e) {
                 Log.d("MyPagerAdapter", "onLongPress: " + position);
             }
         };
     }
    }

    在上面代码中,我通过pagerView显示多个ZoomableDraweeView(实际开发中应该使用动态添加pager的方法初始化pagerView)。具体的方法和展示单个图片差不多,区别在于用在展示多个图片的时候用ViewPager来展示。

小结

从上述代码来看,如果项目是使用fresco来作为图片加载框架的话,那么使用samples包中的ZoomableDraweeView来实现图片的手势放大和缩小时十分简便的。而且在facebook的官方demo中有很多关于fresco的拓展用法,所以在这里笔者推荐,在你使用fresco的时候,更多关于图片操作的拓展功能可以参照或者引用facebook官方demo的方法。

项目代码

项目代码放在笔者平时练习写的一个demo集合里面,通过svn checkout命令下载。

注:这里介绍一个使用github时候的小诀窍给读者。下载一个项目中的单个or部分文件夹的时候,可以通过svn的checkout命令来下载。

具体用法是复制具体文件夹路径,然后把/tree/master/替换成/trunk/。例如,本例子中:

项目地址是:github.com/DobbyTang/A…

下载地址是:github.com/DobbyTang/A…

即svn checkout github.com/DobbyTang/A…

遇到这个提示的时候(R)eject, accept (t)emporarily or accept (p)ermanently? ,输p即可。