date : 2019/10/13
author : lrcoder
分析
RecyclerView 使用的時(shí)候需要關(guān)注三點(diǎn):
- 數(shù)據(jù)來源
- 界面布局
- 適配器設(shè)置
1. 數(shù)據(jù)來源
一般來說,android中的數(shù)據(jù)存放List集合中,數(shù)據(jù)讀取的方式可能會(huì)涉及到線程的耗時(shí)操作,需要適當(dāng)?shù)倪M(jìn)行異步操作。對(duì)于android中的異步操作,這里不作過多分析。
// 創(chuàng)建數(shù)據(jù)源
List<String> mList = new ArrayList<>();
// 獲取數(shù)據(jù)數(shù)據(jù)的部分抽取出來
private void initList() {
// TODO: 2019/10/13 初始化數(shù)據(jù)(數(shù)據(jù)庫(kù)、sharepreference、都可以。)
mList.add("demo");
mList.add("test");
}
2. 界面布局
RecyclerView 支持縱向排列,橫向排列和瀑布流排列。這也是RecyclerView的使用特點(diǎn),需要指定一個(gè)布局管理器,具體代碼:
// 1. 找到recyclerView
RecyclerView recyclerView = this.findViewById(R.id.recyclerView);
// 2. 創(chuàng)建一個(gè)布局管理器
LinearLayoutManager lm = new LinearLayoutManager(this.getApplicationContext());
// 3. 設(shè)置布局為豎直(默認(rèn))
lm.setOrientation(LinearLayoutManager.VERTICAL);
// 4. 將其設(shè)置為該recyclerView的布局管理器
recyclerView.setLayoutManager(lm);
// 5. 為該recyclerView聲明一個(gè)適配器, 并綁定數(shù)據(jù)源
RecyclerViewAdapter adapter = new RecyclerViewAdapter(getApplicationContext(), mList);
// 6. 將這個(gè)適配器與recyclerView進(jìn)行綁定
recyclerView.setAdapter(adapter);
這里,如果需要的是橫向排列,可以將第3步中的布局設(shè)置為
LinearLayoutManager.HORIZONTAL如果需要的是瀑布流形式,可以將第2步的布局管理器換為
StaggeredGridLayoutManager
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
這里,StaggeredGridLayoutManager的第一個(gè)參數(shù)為 3 列,第二個(gè)參數(shù)為豎直排列
3. 適配器設(shè)置(劃重點(diǎn))
RecyclerView 中自帶ViewHolder 視圖處理的方法,但是我們需要手動(dòng)將視圖和界面進(jìn)行綁定,同時(shí)在Adapter中進(jìn)行數(shù)據(jù)綁定、點(diǎn)擊事件設(shè)置,先上碼:
// 自定義的Adapter繼承RecyclerView.Adapter,正如ListView中的Adapter,我們需要對(duì)其寫一個(gè)ViewHolder的內(nèi)部類,在recyclerView中,我們需要在RecyclerView.Adapter中指定我們定義的這個(gè)ViewHolder
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHoldr> {
// 因?yàn)槭荄emo,沒有刻意寫一個(gè)JavaBean類,使用String類型代替一下
List<String> mString;
Context context;
// 構(gòu)造函數(shù),用于外部創(chuàng)建Adapter時(shí)可以對(duì)其傳入數(shù)據(jù)
public RecyclerViewAdapter(Context context, List<String> mString) {
this.mString = mString;
this.context = context;
}
// 綁定視圖
@NonNull
@Override
public ViewHoldr onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 將視圖和item布局進(jìn)行綁定
// 為什么聲明的是View?可以參考RecyclerView.ViewHolder繼承的方法,其中需要傳入一個(gè)View類型的參數(shù)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
// 聲明其中的控件
ViewHoldr viewHoldr = new ViewHoldr(view);
return viewHoldr;
}
// 綁定數(shù)據(jù)
@Override
public void onBindViewHolder(@NonNull ViewHoldr holder, int position) {
// 將數(shù)據(jù)和控件進(jìn)行綁定
String str = mString.get(position);
holder.mTextView.setText(str);
// 設(shè)置點(diǎn)擊事件
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context.getApplicationContext(), "i am clicked", Toast.LENGTH_LONG).show();
}
});
}
@Override
public int getItemCount() {
// 獲取數(shù)據(jù)個(gè)數(shù)
return mString.size();
}
// 1. 內(nèi)部類申明為靜態(tài),防止內(nèi)存泄漏(oom)
// 2. 為item視圖中的每個(gè)控件進(jìn)行申明
static class ViewHoldr extends RecyclerView.ViewHolder {
TextView mTextView;
public ViewHoldr(@NonNull View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textView);
}
}
}