使用RecyclerView打造Gallery

RecyclerView概述

RecyclerView是谷歌推出的用於向大型數據集提供有限窗口的靈活視圖。能夠經過導入support-v7對其進行使用。
據官方的介紹,該控件用於在有限的窗口中展現大量數據集,其實這樣功能的控件咱們並不陌生,例如:ListView、GridView。android

那麼有了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個方法:ide

  • 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。this

  • 在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效果.net

相關文章
相關標籤/搜索