引言
??提起Android開發(fā),你能想到最浪漫的事极祸,就是擼個(gè)炫酷的ListView的Adapter把你的數(shù)據(jù)按列表形式展示出來了吧慈格?其實(shí)大可不必!老套的ListView已經(jīng)不能滿足現(xiàn)在的開發(fā)需求了遥金,缺點(diǎn)相當(dāng)明顯浴捆,比如你想要列表橫向滾動(dòng),你會(huì)發(fā)現(xiàn)ListView無計(jì)可施稿械!
??這就不得不來介紹下今天的主角了:RecyclerView选泻。跟隨我的腳步一起來學(xué)習(xí)吧~
介紹
??RecyclerView是support.v7包中的控件,可以說是ListView和GridView的增強(qiáng)升級版美莫。
??RecyclerView的強(qiáng)大和可擴(kuò)展性離不開其眾多輔助類页眯。其中Adapter和ViewHolder以及LayoutManager是展示列表所必須的,其他輔助類配合能完成更多復(fù)雜炫酷的需求厢呵。
區(qū)別
(1)Listview中ViewHolder是需要自定義的窝撵,在RecyclerView中ViewHolder是谷歌已經(jīng)封裝好的。
(2)Listview中的Item是只能垂直滑動(dòng)的襟铭,RecyclerView可以水平滑動(dòng)或者垂直滑動(dòng)碌奉,針對多種類型條目的展示效果,如瀑布流 網(wǎng)格 支持多種類型寒砖。
(3)Listview中刪除或添加item時(shí)赐劣,item是無法產(chǎn)生動(dòng)畫效果的,在RecyclerView中添加哩都、刪除或移動(dòng)item時(shí)有兩種默認(rèn)的效果可以選擇SimpleItemAnimator(簡單條目動(dòng)畫) 和 DefaultItemAnimator(原樣的條目動(dòng)畫)魁兼。
Tips:RecyclerView還提供了ItemDecoration,可以自定義我們的動(dòng)畫樣式哦漠嵌,后續(xù)我也會(huì)通過博客分享出來璃赡。本文的最后會(huì)先給大家看一下我們自定義動(dòng)畫后實(shí)現(xiàn)的“炫酷”效果。
用法
??第一篇RecyclerView只寫瀑布流的用法献雅,實(shí)現(xiàn)跟ListView同樣的功能碉考,后續(xù)會(huì)分享更多其他比ListView更強(qiáng)大的用法。
第一步:添加相關(guān)依賴(app下build.gradle)
implementation "com.google.android.material:material:1.1.0-alpha07"
第二步:布局文件中使用控件
(1)主布局:activity的xml布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".blog.Case21"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="Recyclerview示例"
app:titleTextColor="@color/white"
android:background="@color/green"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
(2)子布局:R.layout.case7_item_fruit.xml
形式:左邊圖片+右邊文字
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="horizontal"
android:padding="5dp"
tools:ignore="MissingConstraints">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
第三步:創(chuàng)建實(shí)體類Fruit(為RecyclerView填充數(shù)據(jù)使用)
/**
* @data on 2020/8/27 9:47 PM
* @auther ArmStrong
* @describe
*/
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
第四步:創(chuàng)建RecyclerView的適配器類
/**
* @data on 2020/8/28 1:51 PM
* @auther
* @describe
*/
public class FruitRecyclerViewAdapter extends RecyclerView.Adapter<FruitRecyclerViewAdapter.MyViewHolder>{
private List<Fruit> fruitList;
public FruitRecyclerViewAdapter(List<Fruit> fruitList) {
this.fruitList = fruitList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.case7_item_fruit,parent,false);
final MyViewHolder holder = new MyViewHolder(itemView);
return holder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Fruit fruitItem = fruitList.get(position);
holder.fruitImage.setImageResource(fruitItem.getImageId());
holder.fruitName.setText(fruitItem.getName());
//item的點(diǎn)擊事件
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int positon = holder.getAdapterPosition();
Fruit fruit = fruitList.get(positon);
Toast.makeText(v.getContext(),"ver:"+"你點(diǎn)擊了"+fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
View fruitView;
//圖片
public ImageView fruitImage;
//標(biāo)題
public TextView fruitName;
public MyViewHolder(View itemView) {
super(itemView);
fruitView = itemView;
fruitImage = itemView.findViewById(R.id.fruit_image);
fruitName = itemView.findViewById(R.id.fruit_name);
}
}
@Override
public int getItemCount() {
return fruitList.size();
}
}
第五步:Activity中為控件綁定適配器類
public class Case21 extends AppCompatActivity {
private RecyclerView mRecyclerView;
private FruitRecyclerViewAdapter adapter;
private LinearLayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case21);
mRecyclerView = findViewById(R.id.recyclerView);
//RecyclerView填充數(shù)據(jù)
List<Fruit> mList = new ArrayList();
for ( int i=1 ; i<20 ; i++){
mList.add(new Fruit("apple"+i,R.mipmap.apple));
}
//瀑布流布局
adapter = new FruitRecyclerViewAdapter(mList);
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(RecyclerView.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
運(yùn)行效果
本期效果:
后續(xù)達(dá)到的效果:
解析
(1):布局加載分析
??RecyclerView需要通過setLayoutManager()方法設(shè)置布局管理器挺身,同時(shí)需要setAdapter()綁定適配器侯谁,用于填充數(shù)據(jù)。而可以看到RecyclerView是通過自定義ViewHolder的方式來加載的item文件,并且綁定到控件的id墙贱,這一幕何其熟悉热芹,不正是activity的加載布局和定義控件,使用流程嘛惨撇!
(2):填充數(shù)據(jù)分析
??在RecyclerView中伊脓,使用重寫的onBindViewHolder方法來,通過ViewHolder對我們定義和綁定的控件進(jìn)行數(shù)據(jù)填充魁衙。而我們請求的數(shù)據(jù)從哪里來呢报腔?當(dāng)然是從接口請求最后封裝成列表數(shù)據(jù),從而提取出來剖淀,F(xiàn)ruitList其實(shí)就是模擬出了這種情景纯蛾,所以需要我們在Adapter中定義構(gòu)造函數(shù),參數(shù)就是我們的數(shù)據(jù)源:fruitList纵隔。
??而在activity中翻诉,只需要?jiǎng)?chuàng)建該Adapter,調(diào)用其構(gòu)造方法傳遞參數(shù)進(jìn)去捌刮,就可以了碰煌,后續(xù)定義控件以及綁定控件id全部交由Adapter中的ViewHolder幫助我們來完成。
(3):點(diǎn)擊事件分析
??點(diǎn)擊跳轉(zhuǎn)到詳情頁是每個(gè)列表都需要實(shí)現(xiàn)的標(biāo)準(zhǔn)業(yè)務(wù)邏輯绅作,這里的點(diǎn)擊事件就是模擬這個(gè)操作芦圾。而在RecyclerView中點(diǎn)擊事件也不得不借助ViewHolder,在自定義ViewHolder中定義控件和綁定控件的時(shí)候需要定義itemView棚蓄,這樣在onBindViewHolder中就可以通過Viewholder的方式來獲取我們的整個(gè)列表item控件的View布局了堕扶,點(diǎn)擊事件setOnClickListener碍脏,重寫onClick方法就可以了梭依。是不是很簡單!
千夜零一:"之前總是看各種博客學(xué)習(xí)東西典尾,現(xiàn)在我想用博客記錄下我的學(xué)習(xí)腳步役拴,好東西也需要分享,索取和給予是相互的钾埂。以后會(huì)盡量日更的河闰!目標(biāo)完成1001篇博客哈哈∪熳希”
??如果覺得對你有所幫助,請不要吝嗇你的點(diǎn)贊,有問題也可以在下方評論區(qū)留言哦夹囚,關(guān)注我一起學(xué)習(xí)吧~