作者: weiyf
时间: 2016-10-31 14:31:09
原文链接:https://futurestud.io/tutorials/glide-listadapter-listview-gridview

在这个系列的前两篇文章中展示了如何在ImageView去加载单个图片。这篇博客将会演示每一个项只包含单个ImageViewListViewGridView的适配器实现。这就像是很多相册app那样。

The first two posts in this series have shown how to load a single image into an ImageView. This post will demonstrate adapter implementations for ListView and GridView, where each cell contains a single ImageView. This is similar to many image gallery apps.

Glide系列提纲概况(Glide Series Overview):

  1. 【双语】Glide — 入门(Glide — Getting Started)
  2. 【双语】Glide — 高级加载(Glide — Advanced Loading)
  3. 【双语】Glide — 列表适配器(ListView, GridView)(Glide — ListAdapter (ListView, GridView))
  4. Glide — Placeholders & Fade Animations
  5. Glide — Image Resizing & Scaling
  6. Glide — Displaying Gifs & Videos
  7. Glide — Caching Basics
  8. Glide — Request Priorities
  9. Glide — Thumbnails
  10. Glide — Callbacks: SimpleTarget and ViewTarget for Custom View Classes
  11. Glide — Loading Images into Notifications and AppWidgets
  12. Glide — Exceptions: Debugging and Error Handling
  13. Glide — Custom Transformations
  14. Glide — Custom Animations with animate()
  15. Glide — Integrating Networking Stacks
  16. Glide — Customize Glide with Modules
  17. Glide Module Example: Acctupepting Self-Signed HTTPS Certificates
  18. Glide Module Example: Customize Caching
  19. Glide Module Example: Optimizing By Loading Images In Custom Sizes
  20. Glide — Dynamically Use Model Loaders
  21. Glide — How to Rotate Images
  22. Glide — Series Roundup

首先,我们需要准备一些测试图片,我们上传了从我们eatfoody.com项目精选的食谱图片。

First, we’ll need some test images. We uploaded a selection of the best recipe images from our eatfoody.com project to imgur:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static String[] eatFoodyImages = {
"http://i.imgur.com/rFLNqWI.jpg",
"http://i.imgur.com/C9pBVt7.jpg",
"http://i.imgur.com/rT5vXE1.jpg",
"http://i.imgur.com/aIy5R2k.jpg",
"http://i.imgur.com/MoJs9pT.jpg",
"http://i.imgur.com/S963yEM.jpg",
"http://i.imgur.com/rLR2cyc.jpg",
"http://i.imgur.com/SEPdUIx.jpg",
"http://i.imgur.com/aC9OjaM.jpg",
"http://i.imgur.com/76Jfv9b.jpg",
"http://i.imgur.com/fUX7EIB.jpg",
"http://i.imgur.com/syELajx.jpg",
"http://i.imgur.com/COzBnru.jpg",
"http://i.imgur.com/Z3QjilA.jpg",
};

第二,我们需要一个创建一个adapter并将它设置给ListView的activity:

Second, we’ll require an activity, which creates an adapter and sets it for a ListView:

1
2
3
4
5
6
7
8
9
10
11
public class UsageExampleAdapter extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_usage_example_adapter);

listView.setAdapter(new ImageListAdapter(UsageExampleAdapter.this, eatFoodyImages));
}
}

第三,让我们看一下adapter的布局文件。这个ListView的布局文件非常简单:

Third, let’s look at the layout files for the adapter. The layout file for a ListView item is very simple:

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>  
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"/>

这将会显示一个每一项含有一个高度为200dp和填充设备宽度的图片的图片列表。明显这不是一个最漂亮的相册,但是这并不是这篇博客的重点。

This will result in a list of images, which each will have a height of 200dp and match the device’s width. Obviously, this will not result in the prettiest image gallery, but that’s not the focus of this post.

在此之前,我们需要为ListView的实现一个adapter。我们会让它看起来简单和丙丁我们的eatfoody样本图片到adapter。每一个item会显示一个图片。

Before we can jump to the result, we’ll need to implement an adapter for the ListView. We’ll keep it simple and bind our eatfoody example images to the adapter. Each item will display one image.

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
public class ImageListAdapter extends ArrayAdapter {  
private Context context;
private LayoutInflater inflater;

private String[] imageUrls;

public ImageListAdapter(Context context, String[] imageUrls) {
super(context, R.layout.listview_item_image, imageUrls);

this.context = context;
this.imageUrls = imageUrls;

inflater = LayoutInflater.from(context);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = inflater.inflate(R.layout.listview_item_image, parent, false);
}

Glide
.with(context)
.load(imageUrls[position])
.into((ImageView) convertView);

return convertView;
}
}

有趣的事情将会发生在ImageListAdaptergetView()方法。你将会看到Glide调用的方法是和之前常规加载图片的方法完全一样。无论你在应用尝试加载什么,Glide调用的方法还是保持不变。

The interesting stuff happens in the getView() method of the ImageListAdapter. You’ll see that the Glide call is exactly the same as in the previously used ‘regular’ loading of images. The way to utilize Glide stays the same, no matter what application you’re trying to cover.

作为一个进阶的Android开发者,你需要知道我们需要重用ListView的布局,来创造一个快速且顺滑滚动的体验。Glide的魅力是它会自动的处理请求的取消,清空ImageView和加载正确的图片到对应的ImageView

As an advanced Android developer you will know that we need to re-use layouts in ListViews to create a fast & smooth scrolling experience. One awesomeness of Glide is that it automatically takes care of the request canceling, clearing of the ImageViews, and loading the correct image into the appropriate ImageView.

Glide的一个优势:缓存(A Strength of Glide: Caching)

当你多次上下滚动,你将会看到图片会比之前显示的更快。在新的设备中,有可能甚至会没有等待时间。就像你猜的那样,这些图片都是从缓存中来的,并不是从网络加载的。Glide的缓存是基于Picasso实现的,所以这对你来说会更加的全面和做这些事情更加轻松。所实现的缓存大小取决于你的磁盘大小。

When you scroll up and down a lot, you’ll see that the images are displayed much faster than previously. On newer phones, there might be no wait times at all. As you can guess, these images come from cache and are not loaded from the network anymore. Glide’s cache implementation is based on the one from Picasso and thus well rounded and will make things a lot easier for you. The size of the implemented cache depends on the device’s disk size.

当你在加载图片的时候,Glide会使用三种来源:内存,磁盘和网络(从最快到最慢)。再次说明,这里并没有什么你必须去完成的。Glide会为你隐藏所有复杂情况的实现,同时为你创建了只能的缓存大小。我们仔细的在以后的博客中看看这缓存的实现。

When loading an image, Glide uses three sources: memory, disk and network (ordered from fastest to slowest). Once again, there is nothing you’ll have to do. Glide hides all that complexity from you, while creating intelligently sized caches for you. We’ll take a closer look at the caching in a later blog post.

对于带图片的GridView的实现和ListView的实现并没有什么不同。你其实可以使用相同的adapter。只需要在activity中将布局文件改成GridView的:

The implementation for a GridView with image elements is not any different from a ListView implementation. You actually can use the same adapter. Just switch out the activity layout to a GridView:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>  
<GridView
android:id="@+id/usage_example_gridview"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="2"/>

这就是上面设计的效果图:

This will result in the following design:

其他应用:ImageViews作为元素(Other Applications: ImageViews as Elements)

到目前为止,我们只是看到了整个adapter的item是一个ImageView的例子。如果一个或多个ImageView只是adapter item的一个小部分,Glide的加载方式仍然适用。只是你的getView()方法代码看起来会有一点点不同,但是Glide加载item的方式还是相同的。

So far, we’ve only looked at examples where the entire adapter item is an ImageView. The approach still applies if one or more ImageViews are only a (small) part of the adapter item. Your getView() code will look a little different, but the loading of the Glide item would be identical.

展望(Outlook)

在此刻,你已经学习了如何去用Glide加载的90%的Android应用场景。在我们涵盖剩余的案例之前,我们将讲解Glide额外的功能(除了图片加载和缓存)。换句话说,下周我们将会去了解展位图和动画。

At this point, you’ve learned how to load images with Glide in 90% of the Android use cases. Before we cover the edge cases, we’ll explain additional capabilities of Glide (besides image loading and caching). Namely, next week will be all about placeholders and animations.