一、前期基础知识储备
笔者在前面两篇文章《图片加载库Glide精炼详解》、《最强大的列表滚动控件RecyclerView精炼详解》分别介绍了图片加载库Glide和列表滚动控件的常用用法,那么今天本节文章,就开始把两者组合在一起,用Glide请求网络图片,请求完之后将图片用RecyclerView显示出来。
先分析一下思路:单独使用Glide和RecyclerView相信读者都没有问题,那么两者联合使用,关键的联合点在什么地方?——Glide请求的图片相当于RecyclerView中的数据,那么数据的装载发生在什么地方?——数据的装载在适配器中的onBindViewHolder方法里——那么我们就可以得出,关键的联合点在适配器的方法中。
二、上代码,具体实现
第一步:build.gradle文件中添加依赖;
compile'com.github.bumptech.glide:glide:3.7.0'
compile'com.android.support:recyclerview-v7:23.2.1'
compile'com.android.support:cardview-v7:23.3.0'
因为单独的RecyclerView没有默认的分隔线,所以这里我们采用CardView的方式去填充Item子布局,这样得到的显示效果更好。
第二步:主布局文件中添加RecyclerView控件;<?xml version="1.0" encoding="utf-8"?>
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.glideandrecyclerview.MainActivity">
android:id="@+id/recycley_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
第三步:新建Bird实体类,注意里面加入图片名字和图片Url地址两种属性;
public class Bird {
private String name;
private String imageUrl;
//这里注意做一个无参数的构造器
public Bird() {
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageUrl() {
return imageUrl;
}
}
第四步:创建RecyclerView中的子项布局,这里我们依据实体类中定义的属性,放入一个文本控件和ImageView控件,用CardView作为父容器进行包裹;<?xml version="1.0" encoding="utf-8"?>
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
card_view:cardCornerRadius="5dp">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp">
android:id="@+id/bird_image"
android:layout_width="120dp"
android:layout_height="60dp"
android:layout_marginRight="20dp" />
android:id="@+id/bird_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/bird_image"
android:textSize="18sp"
android:textStyle="bold" />
第五步:创建适配器类——核心步骤:public class DataAdapter extends RecyclerView.Adapter {
public Context mContext;
public ArrayList mBirdsList;
//我们在适配器中传入两个参数——当前上下文+数据列表
public DataAdapter(Context context,ArrayList birdList){
mContext = context;
mBirdsList = birdList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
return new ViewHolder(view);
}
//使用Glide的地方——onBindViewHolder方法内部,这个方法适配器用于赋值数据
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(mBirdsList.get(position).getName());
Glide.with(mContext)
.load(mBirdsList.get(position).getImageUrl())
.into(holder.imageView);
}
@Override
public int getItemCount() {
return mBirdsList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
//适配器构造时只会用到实体类的get方法,用以获取相应的属性
imageView = (ImageView) itemView.findViewById(R.id.bird_image);
textView = (TextView) itemView.findViewById(R.id.bird_name);
}
}
}
第六步:主Activity代码中为RecyclerView绑定适配器,同时初始化网络图片数据;public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList birdList;
private DataAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycley_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
birdList = initData();
adapter = new DataAdapter(getApplicationContext(), birdList);
recyclerView.setAdapter(adapter);
}
private final String names[] = {
"Eclair",
"Froyo",
"Gingerbread",
"Honeycomb",
"Ice Cream Sandwich",
"Jelly Bean",
"KitKat",
"Lollipop",
"Marshmallow"
};
private final String imageUrls[] = {
"http://hawksaloft.org/wp-content/uploads/2012/08/614612316_20090805-_mg_3411-rufous-hummingbird-5x7.jpg",
"http://www.gregscott.com/gjs_2007_spring/hummingbird/20070311_1948_100_0560.rufous_humminbird.jpg",
"http://mosthdwallpapers.com/wp-content/uploads/2016/06/Flying-Hummingbird-Pictures.jpg",
"https://wallpapercave.com/wp/alkKAoC.jpg",
"http://mosthdwallpapers.com/wp-content/uploads/2016/06/Gorgeous-Hummingbird-Wallpapers-For-Desktop.jpg",
"http://naturecanada.ca/wp-content/uploads/2014/07/Ruby-throat-Hummingbird-shutterstock_1953533.jpg",
"http://images5.fanpop.com/image/photos/26100000/Hummingbird-hummingbirds-26167630-1024-740.jpgn",
"https://farm5.staticflickr.com/4065/4698051727_5024cd4e6c_b.jpg",
"http://mosthdwallpapers.com/wp-content/uploads/2016/06/Beautiful-Hummingbird-HD-Photography.jpg",
};
private ArrayList initData() {
ArrayList birds = new ArrayList<>();
for (int i = 0; i
Bird bird = new Bird();
bird.setImageUrl(imageUrls[i]);
bird.setName(names[i]);
birds.add(bird);
}
return birds;
}
}
运行效果如下图:
(网络有点波动,有些图片加载较慢)
小结:其实Glide和RecyclerView单独使用都不难,两者联合起来使用实际上也不难,关键是找到二者的联合点,本例中Glide加载的是网络图片,相当于用于填充RecyclerView的数据,那么绑定数据的逻辑是实现在适配器方法中的。想到这一点之后,我们就可以进行处理了。
————————————————————我是分隔线————————————————————
三、二者联合使用的延伸用法
我们已经实现了上面的基础运用,接下来讨论一下一些有用的延伸用法:
(1)运用Glide加载图片的方法,我们要得到圆形图片的效果;
①builde.gradle文件中添加glide-transformations依赖库
compile'jp.wasabeef:glide-transformations:2.0.2'
②在适配器中调用Glide的bitmapTransform方法,将图片变换成圆形;Glide.with(mContext)
.load(mBirdsList.get(position).getImageUrl())
.bitmapTransform(new CropCircleTransformation(mContext))
.into(holder.imageView);
运行效果如图:
其他的更加丰富的图片的处理方法如裁剪、变换、高斯模糊都是一样在适配器内部中实现的。
(2)运用RecyclerView的方法,我们得到瀑布流布局的效果;
①Item_layout布局中,改变文本控件和ImageView的摆放位置;
android:id="@+id/bird_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_below="@id/bird_image"
android:textSize="12sp"
android:textStyle="bold" />
②主Activity代码中,改变RecyclerView的布局方式为瀑布流;StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
运行效果如图:
总结:Glide和RecyclerView的联合使用其实并不复杂,各自做各自的事,找到二者的联合点,然后要实现不一样的布局方式或者展示方式,只需要调用各自的逻辑即可。