RecyclerView 的基本使用
1.新增依賴
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha02'
2.在layout佈局檔案中宣告
activity_main.xml的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3.在當前類中獲取RecyclerView控制元件,並設定介面卡
因為資料是無法直接傳遞給RecyclerView的,所以需要藉助介面卡來完成。 在設定Adapter之前要初始化資料來源,然後通過Adapter的構造方法將資料傳遞給介面卡, 當資料發生變化時我們只需要更新這個資料來源就可以了。
public class MainActivity extends AppCompatActivity {
private ArrayList<Fruit> fruits = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView rv = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(RecyclerView.VERTICAL);
rv.setLayoutManager(layoutManager);
//建立資料來源
initData();
FruitAdapter adapter = new FruitAdapter(fruits);
rv.setAdapter(adapter);
}
}
RecyclerView必須要設定 layoutManager ,通過設定不同的 layoutManager 實現不同形式的列表。
常見的有:
- LinearLayoutManager 縱向/橫向列表
- GridLayoutManager 網格佈局
- StaggeredGridLayoutManager 瀑布流佈局
4. Adapter 的編碼
RecyclerView已經為我們提供了一個介面卡,我們只用繼承它,並且重寫它的三個方法 onCreateViewHolder
、onBindViewHolder
、getItemCount
就可以了 。
- onCreateViewHolder主要是建立ViewHolder例項的, 在這個方法中可以載入子條目的佈局檔案, 設定子條目的點選事件
- onBindViewHolder 主要是為子條目的控制元件進行賦值。 會在每個子條目滾動到螢幕內的時候執行。
- getItemCount()返回的是條目數量,直接返回資料來源的長度即可。
疑問: 那麼onCreatViewHolder什麼時候執行呢? (待理解)
我們定義的ViewHolder只需要繼承Recycler的ViewHolder即可。複用holder的邏輯RecyclerView已經幫我們封裝好了,所以不用像ListView那樣還需要我們自己實現。
ViewHolder 建構函式的引數 itemView 其實就是 RecyclerView 子條目佈局fruit_item(程式碼見下方)的根佈局, 它就是RecyclerView列表中的子條目。 然後使用子條目fruit_item的findViewById()獲取條目中的子View。
具體程式碼如下:
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private static final String TAG = "FruitAdapter";
private final ArrayList<Fruit> mFruits;
public FruitAdapter(ArrayList<Fruit> fruits) {
this.mFruits = fruits;
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivFruit;
TextView tvName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ivFruit = itemView.findViewById(R.id.iv_fruit);
tvName = itemView.findViewById(R.id.tv_name);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruits.get(position);
holder.ivFruit.setImageResource(fruit.getImageId());
holder.tvName.setText(fruit.getName());
}
@Override
public int getItemCount() {
return mFruits.size();
}
}
RecyclerView條目的佈局fruit_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"
xmlns:tool="http://schemas.android.com/tools"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_fruit"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tool:text="蘋果"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
5.設定網格列表和瀑布流
我們可以通過 LayoutManager 來設定佈局的型別。
LinearLayoutManager 為列表型別的佈局, 可以通過setOrientation()
來設定列表的方向。
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//VERTICAL 豎直列表 HORIZONTAL:水平列表
layoutManager.setOrientation(RecyclerView.VERTICAL);
除了設定列表,還可以設定網格列表和瀑布流列表。
設定網格列表程式碼如下:
//引數二: 網格的列數
GridLayoutManager layoutManager = new GridLayoutManager(this, 3);
rv.setLayoutManager(layoutManager);
設定瀑布流
// 引數一:如果瀑布流的方向是vertical, 該引數指定了佈局的列數. 如果瀑布流的方向是horizontal, 該引數指定了佈局的行數
//引數二: 瀑布流的方向
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(layoutManager);
6.為RecyclerView設定點選事件
RecyclerView並沒有像ListView一樣為我們提供類似setOnItemClickListener的條目點選事件, 而是需要我們自己給子項具體的View去註冊點選事件,所以實現起來比ListView要複雜一些。
那麼為什麼RecyclerView在各個方面的設計都要優於ListView, 偏偏在點選事件上卻"沒有處理的非常好"呢? 其實不是這樣的, ListView的點選事件並不人性化, setOnItemClickListener方法註冊的是子條目的點選事件, 但是如果點選的是子條目裡具體的按鈕呢? 雖然ListView也能實現,但是相對就比較麻煩了。 所以,RecyclerView乾脆直接放棄了子條目的點選事件,所以的點選事件都由具體的View去註冊。點選事件的實現方法如下:
首先, 在ViewHolder中新增fruitView變數來儲存子項最外佈局,
static class ViewHolder extends RecyclerView.ViewHolder {
View fruitView;
ImageView ivFruit;
TextView tvName;
ViewHolder(@NonNull View itemView) {
super(itemView);
fruitView = itemView;
ivFruit = itemView.findViewById(R.id.iv_fruit);
tvName = itemView.findViewById(R.id.tv_name);
}
}
然後在onCreateViewHolder()中註冊條目或者條目中子view的點選事件。
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
...
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
//因為fruitView為子條目的最外層佈局,所以該點選事件就是整個條目的點選事件
viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (parent instanceof RecyclerView) {
int position = ((RecyclerView) parent).getChildAdapterPosition(view);
onRecyclerItemClickListener.onRecyclerItemClick(position);
}
}
});
//子項中子view的點選事件
viewHolder.ivFruit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
return viewHolder;
}
private OnRecyclerItemClickListener onRecyclerItemClickListener;
interface OnRecyclerItemClickListener {
void onRecyclerItemClick(int position);
}
@Override
public int getItemCount() {
return mFruits.size();
}
void setOnRecyclerItemClickListener(OnRecyclerItemClickListener onRecyclerItemClickListener) {
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
}
...
}
參考:郭霖《第一行程式碼》
相關文章
- RecyclerView使用指南(一)—— 基本使用View
- RecyclerView的基本設計結構View
- RecyclerView使用View
- RecyclerView的簡單使用View
- Material Design之RecyclerView基本講解與瀑布流的實現Material DesignView
- RecyclerView使用指南(四)—— 使用ItemDecorationView
- RecyclerView使用封裝與優化View封裝優化
- 使用RecyclerView動態改變item時遇到的坑View
- 使用介面實現RecyclerView中的item點選事件View事件
- mongoose的基本使用Go
- Vagrant 的基本使用
- Vuex的基本使用Vue
- JSCore的基本使用JS
- ContentProvider的基本使用IDE
- Promise的基本使用Promise
- APScheduler的基本使用
- selenium的基本使用
- DailyRollingFileAppender的基本使用AIAPP
- pyquery的基本使用
- github的基本使用Github
- MathJax的基本使用
- Class 的基本使用
- git的基本使用Git
- Tomcat的基本使用Tomcat
- jQuery的基本使用jQuery
- 示波器的基本使用:
- IDA的基本使用
- luarocks 的基本使用
- perfdog的基本使用
- mysqli的基本使用MySql
- egg的基本使用
- Vim 基本的使用
- Jedis的基本使用
- mybatis的基本使用MyBatis
- Bootstrap 的基本使用boot
- 與RecyclerView的日常View
- RecyclerView的LinearLayoutManager分析View
- Android中的RecyclerViewAndroidView