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

原创声明: 该文章为原创文章,未经博主同意严禁转载。

摘要:这是一篇关于使用图片加载框架fresco实现图片的手势放大和缩小的教程,希望能对你有所帮助。

前言

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

开发准备

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

1
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文件中添加

1
2
3
4
5
6
7
8
9
10
11
# 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文件中添加

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

    1
    2
    3
    4
    project.ext {
    buildToolsVersion = "${BUILD_TOOLS_VERSION}"
    compileSdkVersion = COMPILE_SDK_VERSION.toInteger()
    }

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

使用教程

查看单个图片

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="utf-8"?\>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.facebook.samples.zoomable.ZoomableDraweeView
    android:id="@+id/zoomableView"
    style="@style/drawee"
    />
    </LinearLayout>

  2. ZoomableActivity.java文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class ZoomableActivity extends Activity {
private ZoomableDraweeView draweeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FLog.setMinimumLoggingLevel(FLog.VERBOSE);
Set<RequestListener> 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文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    android:orientation="horizontal"
    >
    <android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
    android:id="@+id/page1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <com.facebook.samples.zoomable.ZoomableDraweeView
    android:id="@+id/zoomableView1"
    style="@style/drawee"
    />
    </FrameLayout>
    <FrameLayout
    android:id="@+id/page2"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <com.facebook.samples.zoomable.ZoomableDraweeView
    android:id="@+id/zoomableView2"
    style="@style/drawee"
    />
    </FrameLayout>
    <FrameLayout
    android:id="@+id/page3"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <com.facebook.samples.zoomable.ZoomableDraweeView
    android:id="@+id/zoomableView3"
    style="@style/drawee"
    />
    </FrameLayout>
    </android.support.v4.view.ViewPager>
    </LinearLayout>

  2. ZoomableListActivity.java文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class ZoomableListActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FLog.setMinimumLoggingLevel(FLog.VERBOSE);
    Set<RequestListener> 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文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    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/。例如,本例子中:

项目地址是:https://github.com/DobbyTang/AndroidLearnDemo/tree/master/SampleTestDemo

下载地址是:https://github.com/DobbyTang/AndroidLearnDemo/trunk/SampleTestDemo

即svn checkout https://github.com/DobbyTang/AndroidLearnDemo/trunk/SampleTestDemo

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


最近访客