手记

使用Glide+Recycler加载展示网络图片精炼详解

一、前期基础知识储备

笔者在前面两篇文章《图片加载库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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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.support.v7.widget.RecyclerView
        android:id="@+id/recycley_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

第三步:新建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"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    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">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp">


        <ImageView
            android:id="@+id/bird_image"
            android:layout_width="120dp"
            android:layout_height="60dp"
            android:layout_marginRight="20dp" />


        <TextView
            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" />
    </RelativeLayout>

</android.support.v7.widget.CardView>

第五步:创建适配器类——核心步骤

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {

    public Context mContext;
    public ArrayList<Bird> mBirdsList;
	//我们在适配器中传入两个参数——当前上下文+数据列表
    public DataAdapter(Context context,ArrayList<Bird> 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<Bird> 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.jpg\n",
      "https://farm5.staticflickr.com/4065/4698051727_5024cd4e6c_b.jpg",
      "http://mosthdwallpapers.com/wp-content/uploads/2016/06/Beautiful-Hummingbird-HD-Photography.jpg",
    };

    private ArrayList<Bird> initData() {
        ArrayList<Bird> birds = new ArrayList<>();

        for (int i = 0; i < names.length; ++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的摆放位置;

<TextView
            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的联合使用其实并不复杂,各自做各自的事,找到二者的联合点,然后要实现不一样的布局方式或者展示方式,只需要调用各自的逻辑即可。

原文出处

0人推荐
随时随地看视频
慕课网APP