文章歡迎轉載,轉載請註明出處:文章首發於【Karen Chia の 程序人生】- RecyclerView系列 - RecyclerView的基本使用
按照慣例,先上效果圖
這不是我想要的效果圖怎麼辦?
別急,文章末尾有與 RecyclerView 相關的其它文章,請移步 ↓↓↓
前言
RecyclerView 在本文發佈之前,已經出來很久了,之前也有很多關於 RecyclerView 的優秀文章,那我爲什麼還要在這裏寫下本文呢,實不相瞞,我是 ListView 的忠實粉,之前很少使用到 RecyclerView,最近發現了不少關於 RecyclerView 的優秀框架,於是開始使用 RecyclerView,在使用第三方優秀框架的同時,也需要了解框架背後對組件進行的處理及封裝,便於後期對項目維護。
爲什麼選擇 RecyclerView?
相對於 ListView、GridView 這類滑動列表組件來說,RecyclerView 具有:
- 使用更加靈活
1 通過設置佈局管理器,可輕鬆實現組件列表垂直滑動或水平滑動效果
2 給列表的 item 項設置【增加或刪除】動畫
3 當列表組件滑動到頂端或底部時,帶有波紋效果,更顯列表立體感 - 代碼高度解耦
代碼高幅度降低了耦合度,維護起來非常方便 - 拓展方便
1 輕鬆實現 ListView 及 Gridview 組件的相關列表效果,學會 RecyclerView,相當於學會了 ListView + Gridview
2 難得一見的【瀑布流】列表滑動效果
RecyclerView 不是萬能的,存在以下不足:
- 不像 ListView那樣,它沒有分割線的設置方法
- 沒有實現 item 的相關點擊事件
但是,重點來了:
也正是由於 RecyclerView 存在的這些缺點,我們不就可以根據自己的需求去定義嘛,怎麼開心怎麼玩!!!
下面開始進入我們今天的主題 ↓↓↓
1 添加依賴
在 module(一般都是在 app 下) 的 build.gradle 文件下添加組件依賴:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
注意:由於使用的 Android Studio 版本不同,依賴語句也有所不同,我這裏使用的 AS 版本是 V3.4.1
2 在佈局文件中使用 RecyclerView
<?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="match_parent"
android:background="@color/app_bg"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTest"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3 爲 RecycleView 設置佈局管理器 LinearLayoutManager
這裏列表默認是垂直滑動的
rvTest.setLayoutManager(new LinearLayoutManager(this));
不要問我爲什麼,問就【看源碼】,看 LinearLayoutManager 構造器源碼:
/**
* Creates a vertical LinearLayoutManager
*
* @param context Current context, will be used to access resources.
*/
public LinearLayoutManager(Context context) {
this(context, RecyclerView.DEFAULT_ORIENTATION, false);
}
關於 DEFAULT_ORIENTATION 的定義如下:
static final int DEFAULT_ORIENTATION = VERTICAL;
關於 VERTICAL 的定義如下:
public static final int VERTICAL = LinearLayout.VERTICAL;
源碼中使用的屬性還是線性佈局 LinearLayout 的垂直屬性
那麼問題來了,我要讓 RecyclerView 水平滑動怎麼辦?
3.1 設置 RecyclerView 列表水平滑動
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
rvTest.setLayoutManager(mLinearLayoutManager);
4 設置 item 增加和刪除時的動畫效果
rvTest.setItemAnimator(new DefaultItemAnimator());
這裏設置的是 RecyclerView 默認的動畫效果
5 設置適配器
mRecyclerViewTestAdapter = new RecyclerViewTestAdapter(this, testData);
rvTest.setAdapter(mRecyclerViewTestAdapter);
RecyclerView 的適配器繼承至 RecyclerView.Adapter < VH extends ViewHolder >,泛型類型爲ViewHolder。
RecyclerView 對 ViewHolder 進行了封裝,使得我們使用起來更加的方便,自定義的 ViewHolder 只需繼承 RecyclerView.ViewHolder 即可
package com.karenchia.andprimarylp.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.karenchia.andprimarylp.R;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* RecyclerView 測試數據適配器
* <p>
* Created by KarenChia on 2019/9/4.
*/
public class RecyclerViewTestAdapter extends RecyclerView.Adapter<RecyclerViewTestAdapter.RecyclerViewTestViewHolder> {
/**
* 上下文對象
*/
private Context mContext;
/**
* 測試數據
*/
private List<String> testDataList;
/**
* 函數構造器
*
* @param mContext 上下文對象
* @param testDataList 測試數據
*/
public RecyclerViewTestAdapter(Context mContext, List<String> testDataList) {
this.mContext = mContext;
this.testDataList = testDataList;
}
/**
* 加載 item 的佈局文件
*/
@NonNull
@Override
public RecyclerViewTestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new RecyclerViewTestViewHolder(
LayoutInflater.from(mContext).inflate(R.layout.item_recycler_view_test, parent, false));
}
/**
* 將數據與 item 視圖進行綁定
*/
@Override
public void onBindViewHolder(@NonNull RecyclerViewTestViewHolder holder, int position) {
holder.tvData.setText(testDataList.get(position));
}
@Override
public int getItemCount() {
return testDataList == null ? 0 : testDataList.size();
}
/**
* RecycleView 中 ViewHolder 的定義方式
*/
public class RecyclerViewTestViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tvData)
TextView tvData;
public RecyclerViewTestViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
列表 item 佈局文件
<?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"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tvData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black" />
</LinearLayout>
至此,RecyclerView 的基本用法結束。
6 相關類的代碼
這裏貼一下相關類的代碼實現
項目使用的是 MVP 模式,別問我爲什麼要使用 MVP 模式,問就請看這裏:https://blog.csdn.net/ZhaiKun68/article/details/100033584#1_AndroidMVP_3
6.1 RecyclerViewDemoContract 類
package com.karenchia.andprimarylp.ui.contract;
import java.util.List;
/**
* MVP 模式接口抽取
* <p>
* Created by KarenChia on 2019/9/4.
*/
public interface RecyclerViewDemoContract {
interface Model {
/**
* 加載測試數據
*
* @return 測試數據
*/
List<String> testData();
}
interface View {
/**
* 顯示測試數據列表
*
* @param testData 測試數據
*/
void showTestData(List<String> testData);
}
interface Presenter {
/**
* 獲取測試數據
*/
void getTestData();
}
}
6.2 RecyclerViewDemoModel 類
package com.karenchia.andprimarylp.ui.model;
import com.karenchia.andprimarylp.ui.contract.RecyclerViewDemoContract;
import java.util.ArrayList;
import java.util.List;
/**
* model 層數據邏輯處理
* <p>
* Created by KarenChia on 2019/9/4.
*/
public class RecyclerViewDemoModel implements RecyclerViewDemoContract.Model {
/**
* 加載測試數據
*
* @return 測試數據
*/
@Override
public List<String> testData() {
List<String> testData = new ArrayList<>();
for (int i = 0; i < 20; i++) {
testData.add("我是 Karen Chia " + i);
}
return testData;
}
}
6.3 RecyclerViewDemoActivity 類
package com.karenchia.andprimarylp.ui.activity.newfeature;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.karenchia.andprimarylp.R;
import com.karenchia.andprimarylp.adapter.RecyclerViewTestAdapter;
import com.karenchia.andprimarylp.ui.contract.RecyclerViewDemoContract;
import com.karenchia.andprimarylp.ui.presenter.RecyclerViewDemoPresenter;
import com.socks.library.KLog;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* RecyclerView 演示類 view 層邏輯處理
* <p>
* Created by KarenChia on 2019/9/3.
*/
public class RecyclerViewDemoActivity extends AppCompatActivity implements RecyclerViewDemoContract.View {
/**
* view層與model層交互的橋樑
*/
private RecyclerViewDemoContract.Presenter mPresenter;
/**
* RecyclerView 組件
*/
@BindView(R.id.rvTest)
RecyclerView rvTest;
/**
* RecyclerView 的數據適配器
*/
private RecyclerViewTestAdapter mRecyclerViewTestAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view_demo);
ButterKnife.bind(this);
mPresenter = new RecyclerViewDemoPresenter(this);
initData();
initView();
}
private void initData() {
mPresenter.getTestData();
}
/**
* 組件初始化
*/
private void initView() {
//爲 RecycleView 設置佈局管理器
rvTest.setLayoutManager(new LinearLayoutManager(this));
//LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
//mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//rvTest.setLayoutManager(mLinearLayoutManager);
//設置 item 增加和刪除時的動畫效果
rvTest.setItemAnimator(new DefaultItemAnimator());
}
/**
* 顯示測試數據列表
*
* @param testData 測試數據
*/
@Override
public void showTestData(List<String> testData) {
//設置適配器
mRecyclerViewTestAdapter = new RecyclerViewTestAdapter(this, testData);
rvTest.setAdapter(mRecyclerViewTestAdapter);
}
}
6.4 RecyclerViewDemoPresenter 類
package com.karenchia.andprimarylp.ui.presenter;
import com.karenchia.andprimarylp.ui.contract.RecyclerViewDemoContract;
import com.karenchia.andprimarylp.ui.model.RecyclerViewDemoModel;
/**
* model層 與 View層 通信的橋樑
* <p>
* Created by KarenChia on 2019/9/4.
*/
public class RecyclerViewDemoPresenter implements RecyclerViewDemoContract.Presenter {
/**
* model層數據邏輯處理
*/
private RecyclerViewDemoContract.Model mModel;
/**
* view層交互邏輯處理
*/
private RecyclerViewDemoContract.View mView;
public RecyclerViewDemoPresenter(RecyclerViewDemoContract.View mView) {
mModel = new RecyclerViewDemoModel();
this.mView = mView;
}
/**
* 獲取測試數據
*/
@Override
public void getTestData() {
mView.showTestData(mModel.testData());
}
}
看官,如果喜歡我的文章,請點個【關注】唄!!!
後續將繼續推出有關 RecyclerView 的相關用法,盡情期待