日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
那年的RecyclerView我們從頭擼一下

1. RecyclerView是什么?

創(chuàng)新互聯(lián)-專業(yè)網站定制、快速模板網站建設、高性價比芒康網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式芒康網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋芒康地區(qū)。費用合理售后完善,10年實體公司更值得信賴。

根據(jù)Google官方給出的說明:A flexible view for providing a limited window into a large data set。能夠在有限的窗口中展示大數(shù)據(jù)集合的靈活視圖。

所以我們能夠理解為,RecyclerView的一個恰當?shù)氖褂脠鼍笆牵河捎诔叽缦拗?,用戶的設備不能一次性展現(xiàn)所有條目,用戶需要上下滾動以查看更多條目。滾出可見區(qū)域的條目將被回收,并在下一個條目可見的時候被復用。

對于減少內存開銷和CPU的計算,緩存條目是一個非常有用的方法,因為這意味著我們不必每次都創(chuàng)建新的條目,從而減小內存開銷和CPU的計算,而且還能夠有效降低屏幕的卡頓,保證滑動的順滑。

RecyclerView不關心視覺效果(visuals)

但是和ListView有什么區(qū)別呀?我們已經使用ListView很長一段時間了呀,它一樣可以做到呀。從它的類名上看,RecyclerView代表的意義是,我只管Recycler View,也就是說RecyclerView只管回收與復用View,其他的開發(fā)者可以自己去設置。你想要另一個布局?插入另一個LayoutManager。你想要不同的動畫嗎?插入一個ItemAnimator,等等??梢钥闯銎涓叨鹊慕怦睿o予你充分的定制自由(所以你才可以輕松的通過這個控件實現(xiàn)ListView,GirdView,瀑布流等效果)。

2. 引入RecyclerView

RecyclerView 是Support Library的一部分。所以只需要在app/build.gradle中添加以下依賴,便能立即使用:

 
 
 
 
  1. dependencies { compile 'com.android.support:recyclerview-v7:25.3.1'}

在布局文件中加入:

 
 
 
 
  1. android:id="@+id/recycler_view"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent" /> 

然后在頁面中引入RecyclerView即可:

 
 
 
 
  1. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

OK,從現(xiàn)在開始,讓我們一步一步,開始了解它。

3. 使用RecyclerView

下面的表格中就是使用RecyclerView來顯示數(shù)據(jù)中用到的幾個最重要的類,這些類都是RecyclerView的內部類,如果你想使用RecyclerView,需要做以下操作:

Class 功能
Adapter 處理數(shù)據(jù)集合并負責綁定視圖
ViewHolder 持有所有的用于綁定數(shù)據(jù)或者需要操作的View
LayoutManager 負責擺放視圖等相關操作
ItemDecoration 負責繪制Item附近的分割線
ItemAnimator 為Item的一般操作添加動畫效果,如,增刪條目等

我們可以從下圖更直觀的了解到RecyclerView的基本結構:

接下來,我將要描述每個類或接口的內容以及如何使用它。

3.1 RecyclerView.ViewHolder

ViewHolder的基本用法是用來存放View對象。Android團隊很早之前就推薦使用“ViewHolder設計模式”,但是沒有要求開發(fā)者在Adapter中必須使用ViewHolder模式。那么現(xiàn)在對于這種新型的RecyclerView.Adapter,我們必須實現(xiàn)并使用這種模式。

Google官方等了這么長時間才強制使用ViewHolder模式,這有點奇怪,但遲做總比不做好。如果您不了解ViewHolder模式,請查看一下Android training Hold View Objects in a View Holder。另外網上有大量關于ListView優(yōu)化的文章。面試重點。

有一件事是專門針對RecyclerView的。ViewHolder子類可以通過訪問公共成員itemView來訪問ViewHolder的根視圖。所以不需要在ViewHolder子類中存儲。

下面是示例的ViewHolder的代碼,ViewHolder是示例Adapter的內部類:

 
 
 
 
  1. public static class MyViewHolder extends RecyclerView.ViewHolder{        
  2.        TextView tv;
  3.        public MyViewHolder(View itemView) {            
  4.            super(itemView);
  5.            tv = (TextView) itemView.findViewById(R.id.tv);
  6.        }
  7.    } 

3.2 Adapter

Adapter扮演著兩個角色。一是,根據(jù)不同ViewType創(chuàng)建與之相應的的Item-Layout,二是,訪問數(shù)據(jù)集合并將數(shù)據(jù)綁定到正確的View上。這就需要我們重寫以下3個方法:

  • public VH onCreateViewHolder(ViewGroup parent, int viewType) 創(chuàng)建Item視圖,并返回相應的ViewHolder
  • public void onBindViewHolder(VH holder, int position) 綁定數(shù)據(jù)到正確的Item視圖上。
  • public int getItemCount() 返回該Adapter所持有的item數(shù)量

示例代碼如下所示:

 
 
 
 
  1. @Override
  2.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  3.         MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context)
  4.                 .inflate(R.layout.item_recycler_view,parent,false));        
  5.                 return holder;
  6.     }    
  7.     @Override
  8.     public void onBindViewHolder(MyViewHolder holder, int position) {
  9.         holder.tv.setText(mDatas.get(position));
  10.     }    
  11.     @Override
  12.     public int getItemCount() {        
  13.         return mDatas.size();
  14.     } 

因此,一個基本的RecyclerView.Adapter如下:

 
 
 
 
  1. public class RecyclerAdapter extends RecyclerView.Adapter {    
  2.     private Context context;    
  3.     private List mDatas;
  4.     public RecyclerAdapter(Context context, List mDatas) {        
  5.         this.context = context;        
  6.         this.mDatas = mDatas;
  7.     }    
  8.     @Override
  9.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        
  10.         MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context)
  11.                 .inflate(R.layout.item_recycler_view, parent, false));        
  12.         return holder;
  13.     }    
  14.     @Override
  15.     public void onBindViewHolder(MyViewHolder holder, int position) {
  16.         holder.tv.setText(mDatas.get(position));
  17.     }    
  18.     @Override
  19.     public int getItemCount() {        
  20.         return mDatas == null ? 0 : mDatas.size();
  21.     }
  22.     public static class MyViewHolder extends RecyclerView.ViewHolder {        
  23.         TextView tv;
  24.         public MyViewHolder(View itemView) {            
  25.             super(itemView);
  26.             tv = (TextView) itemView.findViewById(R.id.tv);
  27.         }
  28.     }

3.3 RecyclerView.LayoutManager

LayoutManager的職責是擺放Item的位置,并且負責決定何時回收和重用Item。它有一個默認的實現(xiàn):LinearLayoutManager,它可以用于垂直和水平列表。

RecyclerView.LayoutManager是一個抽象類,RecyclerView為我們提供3個實現(xiàn)類:

  1. LinearLayoutManager 現(xiàn)行管理器,支持橫向、縱向。
  2. GridLayoutManager 網格布局管理器
  3. StaggeredGridLayoutManager 瀑布流式布局管理器

3.3.1 LinearlayoutManager

LinearlayoutManager是LayoutManager的默認實現(xiàn)。你可以使用這個類來創(chuàng)建垂直或水平列表。

 
 
 
 
  1. // 設置RecyclerView布局方式為縱向布局
  2. LinearLayoutManager layoutManager = new LinearLayoutManager(context);
  3. layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  4. recyclerView.setLayoutManager(layoutManager); 
 
 
 
 
  1. // 設置RecyclerView布局方式為橫向布局
  2. LinearLayoutManager layoutManager= new LinearLayoutManager(this);
  3. layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
  4. recyclerView.setLayoutManager(layoutManager);

運行程序,我們看到如下效果:

我們發(fā)現(xiàn)和ListView有一些不同,沒有分割線讓這個列表看起來很不美觀,給RecyclerView設置分割線這個我們在下一小節(jié)說明。

當然LinearlayoutManager中還有一些很實用的API:

  • findFirstVisibleItemPosition() 返回當前***個可見Item的position
  • findFirstCompletelyVisibleItemPosition() 返回當前***個完全可見Item的position
  • findLastVisibleItemPosition() 返回當前***一個可見Item的position
  • findLastCompletelyVisibleItemPosition() 返回當前***一個完全可見Item的position

3.3.2 GridLayoutManager

有兩個構造方法:

 
 
 
 
  1. /**
  2. * Creates a vertical GridLayoutManager
  3. *
  4. * @param context Current context, will be used to access resources.
  5. * @param spanCount 設置行數(shù),因為默認是縱向的
  6. */public GridLayoutManager(Context context, int spanCount) {    
  7.     super(context);
  8.     setSpanCount(spanCount);
  9. }/**
  10. * @param context Current context, will be used to access resources.
  11. * @param spanCount 設置行數(shù)或者列數(shù),根據(jù)方向
  12. * @param orientation 布局方向 HORIZONTAL or VERTICAL.
  13. * @param reverseLayout 是否反向顯示 When set to true, layouts from end to start.
  14. */public GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {    
  15.     super(context, orientation, reverseLayout);
  16.     setSpanCount(spanCount);

我們按如下代碼設置:

 
 
 
 
  1. // 設置縱向的4列的表格布局GridLayoutManager layoutManager = new GridLayoutManager(this,4,GridLayoutManager.VERTICAL,false);
  2. recyclerView.setLayoutManager(layoutManager);
  3. // 設置橫向的3行的表格布局GridLayoutManager layoutManager = new GridLayoutManager(this,3,GridLayoutManager.HORIZONTAL,false);
  4. recyclerView.setLayoutManager(layoutManager);  

3.3.3 StaggeredGridLayoutManager

我們來看StaggeredGridLayoutManager的構造方法,只有一個方法

 
 
 
 
  1. /**
  2. * Creates a StaggeredGridLayoutManager with given parameters.
  3. *
  4. * @param spanCount   設置行數(shù)或者列數(shù),根據(jù)方向,縱向就是列數(shù),橫向就是行數(shù)
  5. * @param orientation 方向
  6. */ 
  7. public StaggeredGridLayoutManager(int spanCount, int orientation) {} 

因此我們這樣設置:

 
 
 
 
  1. // 設置縱向的瀑布流布局
  2. StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
  3. recyclerView.setLayoutManager(layoutManager); 

我們看效果和GridLayoutManager沒有什么區(qū)別呢,那我們來小小的修改一下,你就可以看到它的強大。

我們給每個item的布局加入margin:

 
 
 
 
  1.     android:orientation="vertical" android:layout_width="match_parent"
  2.     android:layout_height="wrap_content"
  3.     android:layout_margin="5dp"
  4.     android:background="@color/colorAccent">
  5.     
  6.         android:id="@+id/tv"
  7.         android:layout_width="100dp"
  8.         android:layout_height="100dp"
  9.         android:layout_gravity="center"
  10.         android:gravity="center"
  11.         android:textColor="#fff"
  12.         /> 

然后我們在適配器的onBindViewHolder方法中為我們的item設置個隨機的高度:

 
 
 
 
  1. //貼上部分代碼,其余的請看附件 
  2.     private List mHeights;    
  3.     public RecyclerAdapter(Context context, List mDatas) {        
  4.     this.context = context;        
  5.     this.mDatas = mDatas;
  6.         mHeights = new ArrayList();        
  7.             for (int i = 0; i < mDatas.size(); i++) {
  8.             mHeights.add((int) (100 + Math.random() * 300));
  9.         }
  10.     }
  11.     @Override    
  12.     public void onBindViewHolder(MyViewHolder holder, 
  13.         final int position) {
  14.         ViewGroup.LayoutParams lp = holder.tv.getLayoutParams();
  15.         lp.height = mHeights.get(position);
  16.         holder.tv.setLayoutParams(lp);
  17.     } 

運行,我們可以看到效果,是不是很炫!

3.4 RecyclerView.ItemDecoration

通過設置

 
 
 
 
  1. recyclerView.addItemDecoration(new DividerDecoration(Context context, int orientation));

來改變Item之間的偏移量或者對Item進行裝飾。

例如,在上面的設置LinearlayoutManager之后加入以下代碼,那么列表的效果就會發(fā)生改變:

  1. // 給縱向顯示RecyclerView設置分割線
  2. recyclerView.addItemDecoration(new DividerItemDecoration(activity,DividerItemDecor

    網站欄目:那年的RecyclerView我們從頭擼一下
    瀏覽地址:http://www.dlmjj.cn/article/djjdhsp.html