星期六,又是擼代碼的一天
作為一個初級都算不上的小白,一步一個腳印的學吧,學一個記一個
今天記錄的是RecyclerView
RecyclerView
- 簡述
- 創建布局
- 添加 RecyclerView和每個list布局(偏新手向,選擇性跳過)
- 創建配接器
- 創建
- onCreateViewHolder()
- onBindViewHolder()
- getItemCount()
- 系結配接器
- 創建假資料
- 系結配接器
- 配接器調整
- 區別顯示的實作
- 點擊事件
簡述
官方解釋為:提供一個固定的View讓有限的視窗顯示一個大資料集,(抄的)
我的理解是,和ListView差不多的東西
ListView是什么,不知道
總之,它可以呈現一系列資料,呈現方式可以根據給的LayoutManager確定
瀑布流(StaggeredGridLayoutManager)

串列流 (LinearLayoutManager)

表格流(GridLayoutManager)

使用方式在下面的 系結配接器
創建布局
添加 RecyclerView和每個list布局(偏新手向,選擇性跳過)
第一步當然是在xml中添加,在Palette中找到RecyclerView,右鍵Add添加

又或者在布局中寫入Recy選擇

這時需要給RecyclerView添加id
android:id="@+id/recycler"
然后根據開發需求,創建一個xml檔案,我這里命名為recy_list.xml
作為單個list的布局,我這里模仿聊天界面做了個xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#cccccc"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingRight="20dp"
android:paddingLeft="20dp">
<ImageView
android:id="@+id/head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:src="@android:mipmap/sym_def_app_icon" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="小白"
android:textColor="@color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/news"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#666666"
android:text="今天搬了多少磚"/>
</LinearLayout>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end"
android:textColor="#999999"
android:textSize="14sp"
android:text="2021年4月24日\n19:02:50"/>
</LinearLayout>
最后在Activity系結等等一系列操作
public class MainActivity extends AppCompatActivity {
private RecyclerView recycler;//創建
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();//初始化控制元件方法
}
private void initView() {
recycler = findViewById(R.id.recycler);//系結RecyclerView
}
接下來進入重點,配接器
創建配接器
適配器Adapter,可以讓開發者自定義recyclerview系結的資料,通過上面創建的recy_list檔案模板來創建一堆item
創建
- 創建一個Adapter類
- 繼承RecyclerView的Adapte
- 泛型定義為Adapter的內部類MyHolder
具體是什么我也不知道,一堆復雜的詞
大概就是這樣
public class Adapter extends RecyclerView.Adapter<Adapter.MyHolder> {
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull Adapter.MyHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
}
然后Alt+回車生成一堆Adapter的介面,同時MyHolder變紅,這個不管它,先來看這三方法干啥的
onCreateViewHolder()
- 創建ViewHolder時的回呼函式
- 傳入 ViewGroup parent 和 int viewType
- 回傳 MyHolder
MyHolder是list中每個item
這里使用LayoutInflater布局加載器來加載view,再將view傳給內部類MyHolder用于實體化
private View view;//在外面定義一個view
@NonNull
@Override
public Adapter.MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
view = LayoutInflater.from(context)//實體化LayoutInflater
//傳參 剛才創建的recy_list.xml
.inflate(R.layout.recy_list, parent, false);
Adapter.MyHolder myHolder= new Adapter.MyHolder(view);
return myHolder;
}
(要傳contect,挖坑)
來說一下LayoutInflater,菜鳥教程的解釋 LayoutInflater(布局服務)

然后創建一個內部類MyHolder,繼承ViewHolder ,在里面加上剛才的xml中的控制元件并系結
public class MyHolder extends RecyclerView.ViewHolder {
TextView name, news, time;
ImageView head;
public MyHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
news = itemView.findViewById(R.id.news);
time = itemView.findViewById(R.id.time);
head = itemView.findViewById(R.id.head);
}
}
這時,第一個方法解決了!!
onBindViewHolder()
- 系結ViewHolder時的回呼函式
- 傳入 自定義內部類的 holder 和 int position
激動人心的時候到了,終于系結資料了
position
可以理解為list中item的下標,就像陣列一樣,每個item都有自己的標識
那資料怎么來,Adapter初始唄
新增構造方法,記得要傳context,順便加上成員變數
private Context context;
private ArrayList<String> nameList,newsList,timeList;
public Adapter(Context context, ArrayList nameList ,ArrayList newsList ,ArrayList timeList) {
this.context = context;
this.nameList = nameList;
this.newsList = newsList;
this.timeList = timeList;
}
然后在onBindViewHolder方法中寫系結,根據position來給各個控制元件設定
@Override
public void onBindViewHolder(@NonNull ButViewHolder holder, int position) {
//將資料和控制元件系結
holder.name.setText(nameList.get(position));
holder.news.setText(newsList.get(position));
holder.time.setText(timeList.get(position));
}
就剩最后一個方法了
getItemCount()
沒有傳參,需要回傳一個int
這個方法是控制創建item的條數,回傳的就是條數
我這里直接給其中一個ArrayList的大小即可
@Override
public int getItemCount() {
return nameList.size();
}
三個方法搞定了,意味著這個簡單的Adapter已經寫完了
然后就是讓RecyclerView系結Adapter
系結配接器
在Activity那邊加一個方法,或者直接在onCreate里系結
setRecyclerView();
創建假資料
ArrayList name = new ArrayList();
ArrayList news = new ArrayList();
ArrayList time = new ArrayList();
for (int i= 0;i<20;i++){
name.add("小白 " + i);
news.add("今天搬磚了?");
time.add("2021年4月24日\n19:17:04");
}
系結配接器
//配接器
RecyclerAdapter adapter = new RecyclerAdapter(this,name,news,time);
//布局
LinearLayoutManager manager = new LinearLayoutManager(this);
//設定布局
recycler.setLayoutManager(manager);
//設定影片
recycler.setItemAnimator(new DefaultItemAnimator());
//設定配接器
recycler.setAdapter(adapter);
就這樣搞定了,這時運行專案就可以了看見本文開頭那個串列流的效果了
配接器調整
都寫到這了,再寫一點吧
區別顯示的實作
假如要給某一條item換上不同的背景
這時就需要在onBindViewHolder中修改
通過position,拿到ArrayList的某個資料進行判斷
然后設定這個holder的某個控制元件的屬性即可
點擊事件
都九點半了,六千字,好累,寫目錄時加了這個,想刪又不想刪,還是寫完再回家吧
Adapter點擊事件的實作,需要宣告View.OnClickListener介面
修改Adapter類,宣告View.OnClickListener介面,加上一個onClick方法
public class Adapter
extends RecyclerView.Adapter<Adapter.MyHolder>
implements View.OnClickListener{
@Override
public void onClick(View v) {}
}
想要點擊不同的item時做一些不同的事,就又又又要修改onBindViewHolder
給itemView設定點擊事件
@Override
public void onBindViewHolder(@NonNull ButViewHolder holder, int position) {
//將資料和控制元件系結
holder.name.setText(nameList.get(position));
holder.news.setText(newsList.get(position));
holder.time.setText(timeList.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {}
});
}
就這樣???
如果我想在Activity中設定點擊事件呢,比如跳轉頁面這種情況
添加點擊事件介面,傳值嘛
你想要什么就傳什么,比如我想要點擊的item的name,就傳個name
public interface OnItemClickListener {
void onItemClick(String name);
}
有介面,就要Activity那邊實作,所以Adapter里新增一個方法
同時,介面里的方法需要傳給成員變數
private OnItemClickListener mListener;
public void setOnItemClickListener(OnItemClickListener li) {
mListener = li;
}
最后在系結中的點擊事件中添加
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemClick(nameList.get(position));
}
});
這么說好像有些別扭
總結就是
- Adapter創建點擊事件介面
- Activity實作介面
- 實作后的介面存入Adapter的成員變數
- 當點擊item時,觸發onBindViewHolder中設定的系結事件
- 系結事件執行的是 Activity中傳給成員變數的方法
這時,點擊事件已經完成,就這樣吧,回家咯!
下次有時間寫個加頭或尾的文章類似于B站的獨占一行方法
不要在意內容!!!
對本文有任何意見或疑問,或者認為其中說法有誤,歡迎在評論區留言!!!
最后,轉載請注明出處!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/280223.html
標籤:其他
上一篇:自定義控制元件-時間軸
下一篇:Android——新大陸云平臺篇
