RecyclerView與ListView比較
RecyclerView 概述
RecyclerView 整合自 ViewGroup 。RecyclerView是Android-support-V7版本中新增的一個Widgets,官方對於它的介紹是:RecyclerView是ListView的升級版本,更加先進和靈活。
Android L 之後,Google 提供了RecyclerView檢視化控制元件,5.0之前如果想要使用的話,可以新增V7包以向下相容,提供更全面的API和更靈活的佈局管理。
RecyclerView 做了什麼
- 類似ListView;
- 類似GridView;
- 橫向ListView;
- 橫向GridView;
- 瀑布流式佈局
RecyclerView 組成
- RecyclerView.LayoutManager
- RecyclerView.Recyler
- RecyclerView.Adapter
- RecyclerView.ViewHolder
- RecyclerView.ItemDecoration
- RecyclerView.ItemAnimator
機制:layoutmanager 從Recycle 中獲取已經繫結資料的 Item 顯示,並將不再需要的Item 丟給Recycler 回收;Adapter 負責生成新Item 並將其繫結好資料,供Recyle獲取;Recycler 就是子 Item 的一個快取池。
RecyclerView.LayoutManager -- 管理子View佈局的一個元件
主要負責:佈局子檢視、滾動子檢視在滾動過程中根據子檢視在佈局中所處的位置,決定何時新增子檢視和刪除子檢視。
涉及到的API:
- 獲取佈局尺寸
setRecyclerView()、setMeasureSpecs()、setMeasuredDimensionFromChildren() - 可以設定和獲取方向的水平或垂直
canScrollHorizontally()、canScrollVertically()、setOrientation()、getOrientation() - 滑動狀態改變時RecyclerView呼叫方法通知LayoutManager
onScrollStateChanged(() - 增、刪、移動子View
addView()、removeView()、moveView()、removeAllViews()、removeViewAt() - 獲取指定位置的View
getPosition()、getChildAt()、findViewByPosition() - 獲取可見子View及全部子View的個數
getChildCount()、getItemCount() - 移除資料後呼叫了recycler進行資料的快取
detachView()、detachAndScrapAttachedViews()、removeAndRecycleAllViews()、scrapOrRecycleView()
RecyclerView.Adapter 負責資料、Item的生成和資料的繫結
Adapter 有幾個抽象方法需要子類實現:
- 返回一個ViewHolder 封裝例項
onCreateViewHolder() - 根據ViewHolder對應的View進行資料繫結
onBindViewHolder() - 獲取總數
getItemCount() - 獲取不同Type型別的View,為新增 header 和 footer 預留介面
getItemViewType() - 指定位置的 item 內容發生了變化
notifyItemChanged() - 在指定的位置處插入一個 Item
notifyItemInserted() - 指定位置的兩個 Item 進行交換
notifyItemMoved(int, int)
RecyclerView.Recyler 負責 Item 的快取
即提供新的,也回收舊的(強大就強大在View的迴圈回收利用)
- RecyclerView 的二級快取:
有兩個快取:Scrap 和 Recycle ,Scrap 中文是廢料的意思。Recycle 對應是回收的意思。
Scrap 快取是指裡面快取的View 是接下來需要用到的,不需要新繫結資料,是一個輕量級的快取集合,而Recycle 的快取的 View 為裡面的資料需要重新繫結,都放在RecyclerViewPool 池中,都需要通過 Adapter 重新繫結資料。 - RecyclerView 快取的兩種方式:
Detach 和 Remove ,Detach 的View 放在Scrap 快取中,Remove 掉的View 放在 RecyclerViewPool快取池中。 - 使用場景:
反覆去將View移除並且馬上又要新增進去時,選擇Detach 方式,通過方法 detachAndScrapView()實現。使用頻率很低,螢幕中不顯示的時候使用Remove 的方式,通過方法 removeAndRecycleView()實現。 - 複用流程:
當我們去獲取一個新的View時,首先去檢查Scrap 快取是否有對應的 position 的View ,如果有直接用;如果沒有,則從RecyclerViewPool快取池中取,並且會回撥Adapter 的onBindViewHolder 方法(如果Recycle 快取為空,還會呼叫onCreateViewHolder方法),最後再將繫結好新資料的View返回。
相關方法
與Recycler相關:
- 獲取快取最大閥值,閥值為2
setItemViewCacheSize() - 從快取中取Item
getViewForPosition() - 獲取Scrap 快取列表
getScrapList() - 從Layoutmanager 回收Item
recyclerView() - 回收後,快取型別的內部處理邏輯
recyclerViewHolderInternal() - 根據Adapter 變化,轉換Item 快取如pool
onAdapterChanged() - 呼叫此方法返回一個RecyclerViewPool 例項
getRecyclerView() - 快取如pool
addViewHolderToRecyclerViewPool()
RecyclerViewPool 相關:
- 快取的不同型別ViewType的數量是不限的,但是每個viewType 的具體ViewHolder 最多為5個
setMaxRecycledViews(int viewType,int max) - 存入viewHolder
putRecycledView() - 。。。
getRecycledView()
RecyclerViw 與 listView 比較
- Item 回收/複用方面:後者是以convertView 作為回收單位,需要手動新增ViewHolder ,而前者則是以ViewHolder作為回收單位,convertView 被內建到了ViewHolder 中作為 ViewHolder 的成員變數,前者內建了Recycle 、多級快取。
- 樣式豐富方面:前者通過支援水平、垂直和變革列表及其他更復雜形式,而後者只支援具體某一種
- 效果增強方面:前者內建了ItemDecoration 和 ItemAnimator ,可以自定義繪製 itemView 之間的一些特殊UI 或Item 項資料變化時的動畫效果,而yoga後者實現比較麻煩。
- 程式碼內聚方面:前者將功能密切相關的類攜程內部類,如ViewHolder,Adapter。而後者沒有。
adapter用法
- ListView 的 adapter
class MyAdapter extends BaseAdapter {
……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
…… //初始化convertView和ViewHolder
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
……
}
}
static class ViewHolder {
TextView txvTitle;
}
- RecyclerView 的 adapter
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
@Override
public int getItemCount() {
return 0;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
}
class MyViewHolder extends RecyclerView.ViewHolder {
//TODO 初始化控制元件
public MyViewHolder(View itemView) {
super(itemView);
}
}
}
最基礎的adapter,應用中列表會有許多,有多少個列表就會有幾個介面卡,可以根據需求封裝adapter,以方便使用。
相關文章
- ListView 與 RecyclerView 簡單對比View
- ==與equals比較
- Vuex與Redux比較VueRedux
- Hibernate與mybatis比較MyBatis
- yarn 與 npm 比較YarnNPM
- Vue與React比較VueReact
- React與Vue模板使用比較(一、vue模板與React JSX比較)ReactVueJS
- Goland與vscode比較 - redditGoLandVSCode
- Python與Excel VBA比較PythonExcel
- Flutter與Swift比較 - evroneFlutterSwiftVR
- volatile與Atomic的比較
- Kanban與Scrum比較 - modernanalystScrumNaN
- Flutter 與 iOS 功能比較FlutteriOS
- Spring Boot與Micronaut比較Spring Boot
- SOA 、MSA與CNA比較
- Android 列表(ListView、RecyclerView)不斷重新整理最佳實踐AndroidView
- DDD中事件與命令比較事件
- OpenShift與Docker全方位比較Docker
- XTask與RxJava的使用比較RxJava
- Flutter與React Native的比較FlutterReact Native
- PostgreSQL與MySQL的比較 - hackrMySql
- Rust, Go與Hasekll比較 - RedditRustGo
- Apache Sqoop與Apache Flume比較ApacheOOP
- initialize方法與load方法比較
- Spring Boot與Eclipse MicroProfile比較Spring BootEclipse
- JavaScript與WebAssembly進行比較JavaScriptWeb
- MVVM與MVC模式的比較MVVMMVC模式
- Go 與 C++ 的對比和比較GoC++
- js 深比較和淺比較JS
- Java JIT與AOT效能比較 - foojayJava
- 微服務中GraphQL與RESTful比較微服務REST
- Querydsl與JPA標準的比較
- Go與C#的比較 - RedditGoC#
- 雲原生Java與Golang比較 -lgorJavaGolang
- OSI模型 與 DOD模型的比較模型
- ETL介紹與ETL工具比較
- Docker 與 Podman 容器管理的比較Docker
- TomEE、Spring Boot與Quarkus比較 - BaptistaSpring BootAPT