使用RecyclerView打造Gallery

RecyclerView概述

RecyclerView是谷歌推出的用于向大型数据集提供有限窗口的灵活视图。可以通过导入support-v7对其进行使用。
据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView。

那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,这个只能自己写了……

基本使用

mRecyclerView = findView(R.id.id_recyclerview);
//设置布局管理器
mRecyclerView.setLayoutManager(layout);
//设置adapter
mRecyclerView.setAdapter(adapter)
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//添加分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(
                getActivity(), DividerItemDecoration.HORIZONTAL_LIST));

具体使用请参开Android RecyclerView 使用完全解析 体验艺术般的控件

使用RecyclerView创建Gallery

  • Activity布局
<RelativeLayout 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.support.v7.widget.RecyclerView  
        android:id="@+id/id_recyclerview_horizontal"  
        android:layout_width="match_parent"  
        android:layout_height="120dp"  
        android:layout_centerVertical="true"  
        android:background="#FF0000"  
        android:scrollbars="none" />  
  
</RelativeLayout>  
  • Item布局
<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="120dp"  
    android:layout_height="120dp"  
    android:background="@drawable/item_bg02" >  
  
    <ImageView  
        android:id="@+id/id_index_gallery_item_image"  
        android:layout_width="80dp"  
        android:layout_height="80dp"  
        android:layout_alignParentTop="true"  
        android:layout_centerHorizontal="true"  
        android:layout_margin="5dp"  
        android:scaleType="centerCrop" />  
  
    <TextView  
        android:id="@+id/id_index_gallery_item_text"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_below="@id/id_index_gallery_item_image"  
        android:layout_centerHorizontal="true"  
        android:layout_marginBottom="5dp"  
        android:layout_marginTop="5dp"  
        android:textColor="#ff0000"  
        android:text="some info"  
        android:textSize="12dp" />  
  
</RelativeLayout>  
  • 适配器
public class GalleryAdapter extends  
        RecyclerView.Adapter<GalleryAdapter.ViewHolder>  
{  
  
    private LayoutInflater mInflater;  
    private List<Integer> mDatas;  
  
    public GalleryAdapter(Context context, List<Integer> datats)  
    {  
        mInflater = LayoutInflater.from(context);  
        mDatas = datats;  
    }  
  
    public static class ViewHolder extends RecyclerView.ViewHolder  
    {  
        public ViewHolder(View arg0)  
        {  
            super(arg0);  
        }  
  
        ImageView mImg;  
        TextView mTxt;  
    }  
  
    @Override  
    public int getItemCount()  
    {  
        return mDatas.size();  
    }  
  
    /** 
     * 创建ViewHolder 
     */  
    @Override  
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)  
    {  
        View view = mInflater.inflate(R.layout.activity_index_gallery_item,  
                viewGroup, false);  
        ViewHolder viewHolder = new ViewHolder(view);  
  
        viewHolder.mImg = (ImageView) view  
                .findViewById(R.id.id_index_gallery_item_image);  
        return viewHolder;  
    }  
  
    /** 
     * 设置值 
     */  
    @Override  
    public void onBindViewHolder(final ViewHolder viewHolder, final int i)  
    {  
        viewHolder.mImg.setImageResource(mDatas.get(i));  
    }  
  
} 

可以看到数据适配器与BaseAdapter比较发生了相当大的变化,主要有3个方法:

  • getItemCount 这个不用说,获取总的条目数
  • onCreateViewHolder 创建ViewHolder
  • onBindViewHolder 将数据绑定至ViewHolder

可见,RecyclerView对ViewHolder也进行了一定的封装,但是ListView里面有个getView返回View为Item的布局,那么这个Item的样子在哪控制?

其实是这样的,我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder的构造时必须传入一个View,这个View相当于我们ListView getView中的convertView (即:我们需要inflate的item布局需要传入)。

还有一点,ListView中convertView是复用的,在RecyclerView中,是把ViewHolder作为缓存的单位了,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设没有屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder。

  • 在Activity中使用
public class MainActivity extends Activity  
{  
  
    private RecyclerView mRecyclerView;  
    private GalleryAdapter mAdapter;  
    private List<Integer> mDatas;  
      
      
    @Override  
    protected void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.activity_main);  
          
        initDatas();  
        //得到控件  
        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview_horizontal);  
        //设置布局管理器  
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);  
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);  
        mRecyclerView.setLayoutManager(linearLayoutManager);  
        //设置适配器  
        mAdapter = new GalleryAdapter(this, mDatas);  
        mRecyclerView.setAdapter(mAdapter);  
  
          
    }  
  
  
    private void initDatas()  
    {  
        mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.a,  
                R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,  
                R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.l));  
    }  
  
}  

为ReclerView添加OnItemClickListener回调

  • 在Adapter中添加这个回调接口
public class GalleryAdapter extends  
        RecyclerView.Adapter<GalleryAdapter.ViewHolder>  
{  
  
    /** 
     * ItemClick的回调接口 
     * @author zhy 
     * 
     */  
    public interface OnItemClickLitener  
    {  
        void onItemClick(View view, int position);  
    }  
  
    private OnItemClickLitener mOnItemClickLitener;  
  
    public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)  
    {  
        this.mOnItemClickLitener = mOnItemClickLitener;  
    }  
  
    private LayoutInflater mInflater;  
    private List<Integer> mDatas;  
  
    public GalleryAdapter(Context context, List<Integer> datats)  
    {  
        mInflater = LayoutInflater.from(context);  
        mDatas = datats;  
    }  
  
    public static class ViewHolder extends RecyclerView.ViewHolder  
    {  
        public ViewHolder(View arg0)  
        {  
            super(arg0);  
        }  
  
        ImageView mImg;  
        TextView mTxt;  
    }  
  
    @Override  
    public int getItemCount()  
    {  
        return mDatas.size();  
    }  
  
    @Override  
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)  
    {  
        View view = mInflater.inflate(R.layout.activity_index_gallery_item,  
                viewGroup, false);  
        ViewHolder viewHolder = new ViewHolder(view);  
  
        viewHolder.mImg = (ImageView) view  
                .findViewById(R.id.id_index_gallery_item_image);  
        return viewHolder;  
    }  
  
    @Override  
    public void onBindViewHolder(final ViewHolder viewHolder, final int i)  
    {  
        viewHolder.mImg.setImageResource(mDatas.get(i));  
  
        //如果设置了回调,则设置点击事件  
        if (mOnItemClickLitener != null)  
        {  
            viewHolder.itemView.setOnClickListener(new OnClickListener()  
            {  
                @Override  
                public void onClick(View v)  
                {  
                    mOnItemClickLitener.onItemClick(viewHolder.itemView, i);  
                }  
            });  
  
        }  
  
    }  
  
} 
  • 在主Activity中设置监听
mAdapter = new GalleryAdapter(this, mDatas);  
mAdapter.setOnItemClickLitener(new OnItemClickLitener()  
{  
    @Override  
    public void onItemClick(View view, int position)  
    {  
        Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT)  
                .show();  
    }  
});  
mRecyclerView.setAdapter(mAdapter);  

参考 Android 自定义RecyclerView 实现真正的Gallery效果

原文地址:https://www.cnblogs.com/xl-phoenix/p/6794552.html