自Android 5.0之后,谷歌公司推出了RecylerView控件,RecylerView,我想看到一個(gè)新名詞后大部分人會(huì)首先發(fā)出一個(gè)疑問,recylerview是什么?為什么會(huì)有recylerview也就是說recylerview的優(yōu)點(diǎn)是什么?recylerview怎么用?接下來就對(duì)這幾個(gè)問題來一起討論一下recylerview.
通過本篇博客,你將學(xué)到以下知識(shí)點(diǎn)
①RecyclerView與ListView相比它的優(yōu)點(diǎn)
②RecyclerView的初步用法
③RecyclerView增加分隔線
④RecyclerView更改分隔線的樣式
⑤RecyclerView的Adapter的用法
⑥RecyclerView.Adapter中刷新的幾個(gè)方法的對(duì)比
⑦給RecyclerView增加條目點(diǎn)擊事件
1.RecyclerView是什么?
RecylerView是support-v7包中的新組件,是一個(gè)強(qiáng)大的滑動(dòng)組件,與經(jīng)典的ListView相比,同樣擁有item回收復(fù)用的功能,這一點(diǎn)從它的名字recylerview即回收view也可以看出。看到這也許有人會(huì)問,不是已經(jīng)有ListView了嗎,為什么還要RecylerView呢?這就牽扯到第二個(gè)問題了。
2.RecyclerView的優(yōu)點(diǎn)是什么?
根據(jù)官方的介紹RecylerView是ListView的升級(jí)版,既然如此那RecylerView必然有它的優(yōu)點(diǎn),現(xiàn)就RecylerView相對(duì)于ListView的優(yōu)點(diǎn)羅列如下:
①RecylerView封裝了viewholder的回收復(fù)用,也就是說RecylerView標(biāo)準(zhǔn)化了ViewHolder,編寫Adapter面向的是ViewHolder而不再是View了,復(fù)用的 邏輯被封裝了,寫起來更加簡單。
②提供了一種插拔式的體驗(yàn),高度的解耦,異常的靈活,針對(duì)一個(gè)Item的顯示RecylerView專門抽取出了相應(yīng)的類,來控制Item的顯示,使其的擴(kuò)展性非常強(qiáng)。例如:你想控制橫向或者縱向滑動(dòng)列表效果可以通過LinearLayoutManager這個(gè)類來進(jìn)行控制(與GridView效果對(duì)應(yīng)的是GridLayoutManager,與瀑布流對(duì)應(yīng)的還有StaggeredGridLayoutManager等),也就是說RecylerView不再拘泥于ListView的線性展示方式,它也可以實(shí)現(xiàn)GridView的效果等多種效果。你想控制Item的分隔線,可以通過繼承RecylerView的ItemDecoration這個(gè)類,然后針對(duì)自己的業(yè)務(wù)需求去抒寫代碼。
③可以控制Item增刪的動(dòng)畫,可以通過ItemAnimator這個(gè)類進(jìn)行控制,當(dāng)然針對(duì)增刪的動(dòng)畫,RecylerView有其自己默認(rèn)的實(shí)現(xiàn)。
RecyclerView 是一個(gè)增強(qiáng)版的ListView,不僅可以實(shí)現(xiàn)和ListView同樣的效果,還優(yōu)化了ListView中存在的各種不足之處
ResyslerView 能夠?qū)崿F(xiàn)橫向滾動(dòng),這是ListView所不能實(shí)現(xiàn)的
目前官方更加推薦使用RecyclerView.
1.實(shí)現(xiàn)垂直方向的滾動(dòng)
在 dependencies 中添加庫的引用
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.2.0' compile 'com.android.support:recyclerview-v7:24.2.1' }
添加布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </LinearLayout>
創(chuàng)建RecyclerView 適配器 BookBaseAdapter ,這個(gè)類繼承 RecyclerView.Adapter 并將泛型指定為 BookBaseAdapter.ViewHolder
其中ViewHolder是我們?cè)?nbsp;BookBaseAdapter 中定義的一個(gè)內(nèi)部類:代碼如下:
public class BookBaseAdapter extends RecyclerView.Adapter<BookBaseAdapter.ViewHolder>{ private List<Book> mBookList; static class ViewHolder extends RecyclerView.ViewHolder{ ImageView bookImage; TextView bookname; public ViewHolder(View view) { super(view); bookImage = (ImageView) view.findViewById(R.id.book_iamge); bookname = (TextView) view.findViewById(R.id.book_name); } } public BookBaseAdapter(List<Book> mBookList) { this.mBookList = mBookList; }
<span style="white-space:pre;"> </span>//加載item 的布局 創(chuàng)建ViewHolder實(shí)例 @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.book,parent,false); ViewHolder holder = new ViewHolder(view); return holder; }
<span style="white-space:pre;"> </span>//對(duì)RecyclerView子項(xiàng)數(shù)據(jù)進(jìn)行賦值 @Override public void onBindViewHolder(ViewHolder holder, int position) { Book book = mBookList.get(position); holder.bookname.setText(book.getName()); holder.bookImage.setImageResource(book.getImageId()); }
<span style="white-space:pre;"> </span>//返回子項(xiàng)個(gè)數(shù) @Override public int getItemCount() { return mBookList.size(); } }
MainActivity調(diào)用:
public class MainActivity extends AppCompatActivity { private List<Book> mlsit = new ArrayList<Book>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化List數(shù)據(jù) initBook(); //初始化RecyclerView RecyclerView recyslerview = (RecyclerView) findViewById(R.id.recycler_view); //創(chuàng)建LinearLayoutManager 對(duì)象 這里使用 <span style="font-family:'Source Code Pro';">LinearLayoutManager 是線性布局的意思</span> LinearLayoutManager layoutmanager = new LinearLayoutManager(this); //設(shè)置RecyclerView 布局 recyslerview.setLayoutManager(layoutmanager); //設(shè)置Adapter BookBaseAdapter adapter = new BookBaseAdapter(mlsit); recyslerview.setAdapter(adapter); } private void initBook(){ for (int i = 0; i < 10; i++) { Book book01 = new Book("Book"+i,R.drawable.icon01); mlsit.add(book01); Book book02 = new Book("Book"+i,R.drawable.icon02); mlsit.add(book02); Book book03 = new Book("Book"+i,R.drawable.icon03); mlsit.add(book03); } } }
main_layout布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </LinearLayout>
item布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/book_iamge" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/book_name" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
此處省略Book對(duì)象的相關(guān)源碼。如上就可以實(shí)現(xiàn)和ListView一樣的效果。
2.實(shí)現(xiàn)橫向滾動(dòng)
對(duì)垂直布局中的代碼做小修改:
onCreat方法中添加setOrientation()方法來設(shè)置布局的排列方向
layoutmanager.setOrientation(LinearLayoutManager.HORIZONTAL);
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化List數(shù)據(jù) initBook(); //初始化RecyclerView RecyclerView recyslerview = (RecyclerView) findViewById(R.id.recycler_view); //創(chuàng)建LinearLayoutManager 對(duì)象 LinearLayoutManager layoutmanager = new LinearLayoutManager(this); layoutmanager.setOrientation(LinearLayoutManager.HORIZONTAL); //設(shè)置RecyclerView 布局 recyslerview.setLayoutManager(layoutmanager); //設(shè)置Adapter BookBaseAdapter adapter = new BookBaseAdapter(mlsit); recyslerview.setAdapter(adapter); }
修改一下item的布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="150dp" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/book_iamge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"/> <TextView android:id="@+id/book_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_gravity="center_horizontal"/> </LinearLayout>
運(yùn)行程序就可以發(fā)現(xiàn)我們實(shí)現(xiàn)了橫向的滾動(dòng)效果
3.瀑布流布局
RecyclerView除了LinearLayoutManager 之外,還提供了GridlayoutManager和StaggeredGridlayoutManager這兩種內(nèi)置的布局排列方式
GridlayoutManager可以用于實(shí)現(xiàn)網(wǎng)格布局
StaggeredGridlayoutManager可以用于實(shí)現(xiàn)瀑布流布局,
這里我們來實(shí)現(xiàn)一下炫酷的瀑布流布局:
修改item.xml的布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:orientation="vertical"> <ImageView android:id="@+id/book_iamge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"/> <TextView android:id="@+id/book_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_gravity="left"/> </LinearLayout>
onCreat方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化List數(shù)據(jù) initBook(); //初始化RecyclerView RecyclerView recyslerview = (RecyclerView) findViewById(R.id.recycler_view); //創(chuàng)建LinearLayoutManager 對(duì)象 /* * 第一個(gè)參數(shù)表示布局的列數(shù) * 第二個(gè)參數(shù)表示布局的方向,這里我們傳入StaggeredGridLayoutManager.VERTICAL,表示布局縱向排列 */ StaggeredGridLayoutManager layoutmanager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL); //設(shè)置RecyclerView 布局 recyslerview.setLayoutManager(layoutmanager); //設(shè)置Adapter BookBaseAdapter adapter = new BookBaseAdapter(mlsit); recyslerview.setAdapter(adapter); }
僅僅修改一行代碼,就可以成功的實(shí)現(xiàn)瀑布流的布局效果
給RecyclerView的Item添加點(diǎn)擊事件
Item的點(diǎn)擊事件RecyclerView監(jiān)聽事件處理在ListView使用的時(shí)候,該控件給我們提供一個(gè)onItemClickListener監(jiān)聽器,這樣當(dāng)我們點(diǎn)擊Item的時(shí)候,會(huì)回調(diào)相關(guān)的方法,以便我們方便處理Item點(diǎn)擊事件。對(duì)于RecyclerView來講,非??上У氖牵摽丶]有給我們提供這樣的內(nèi)置監(jiān)聽器方法,不過我們可以進(jìn)行改造實(shí)現(xiàn),可以這樣實(shí)現(xiàn)Item的點(diǎn)擊事件的監(jiān)聽,在我們的adapter中增加這兩個(gè)方法
public interface OnItemClickListener{ void onClick( int position); void onLongClick( int position); } public void setOnItemClickListener(OnItemClickListener onItemClickListener { this. mOnItemClickListener=onItemClickListener; }
然后onBindViewHolder方法要做如下更改
@Override public void onBindViewHolder(MyViewHolder holder, final int position) { holder. tv.setText( mDatas.get(position)); if( mOnItemClickListener!= null){ holder. itemView.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onClick(position); } }); holder. itemView.setOnLongClickListener( new OnLongClickListener() { @Override public boolean onLongClick(View v) { mOnItemClickListener.onLongClick(position); return false; } }); } }
在MainAcitivity中增加
recycleAdapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onLongClick(int position) { Toast.makeText(MainActivity.this,"onLongClick事件 您點(diǎn)擊了第:"+position+"個(gè)Item",0).show(); } @Override public void onClick(int position) { Toast.makeText(MainActivity.this,"onClick事件 您點(diǎn)擊了第:"+position+"個(gè)Item",0).show(); } });
如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇