Android Widget:RecyclerView (一)
阿新 • • 發佈:2018-11-26
RecyclerView的基本操作
我也不曉得為何第一個GIF花屏了,我用AS的AVD錄屏的,播放完好,覺得是CS/DN的鍋
列表展示
訊息列表
RecyclerView的使用
RecyclerView通過LinearLayoutManager和Adapter來管理佈局和適配View中的每一個子項
大致分為五個步驟
新增RecyclerView支援
在app目錄下的build.gradle的dependencies中新增implementation ‘com.android.support:recyclerview-v7:25.3.1’
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:recyclerview-v7:25.3.1'//可以到SDK目錄下extras\android\m2repository\com\android\support中檢視版本填寫版本號
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
同步後即可使用該控制元件
RecyclerView的使用
這裡給出圖一的Fruit實現程式碼
首先根據子項item期望的顯示方式建立佈局檔案
圖中的佈局檔案如下
//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"
android:orientation="horizontal">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="20dp"
android:layout_marginStart="10dp" />
</LinearLayout>
建立Fruit類
//Fruit.java
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 int getImageId() {
return imageId;
}
}
建立介面卡FruitAdapter類
程式碼詳解已在註釋中
//FruitAdapter.java
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
//FruitAdapter繼承自RecyclerView.Adapter並規定是配的型別為FruitAdapter.ViewHolder
private List<Fruit> mFruitList;//資料來源,所有Fruit都引用到這裡去適配
public FruitAdapter(List<Fruit> mFruitList) {
this.mFruitList = mFruitList;
}
static class ViewHolder extends RecyclerView.ViewHolder {
//FruitAdapter類中定義的靜態內部類,繼承自RecyclerView.ViewHolder
private ImageView fruitImage;
private TextView fruitName;//每個ViewHolder物件要儲存的控制元件
public ViewHolder(View itemView) {
super(itemView);
fruitImage = itemView.findViewById(R.id.fruit_image);//定位到fruit_item中的ImageView
fruitName = itemView.findViewById(R.id.fruit_name);//定位到fruit_item中的TextView
}
}
@Override
public FruitAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fruit_item,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//渲染item的View並製造ViewHolder的物件儲存該View
//LayoutInflater.from(Context context)從一個Context中,獲得一個佈局填充器,inflate(int R.layout.xml,ViewGroup root,boolean attachToRoot)使用這個填充器按照xml佈局檔案填充一個佈局/View物件
//引數說明 稍後詳解
//R.layout.xml 期望的item佈局檔案
//ViewGroup root 根佈局 依照該佈局填充出View ViewGroup的繼承關係: View -> ViewGroup -> Layout
//boolean attachToRoot attachToRoot為true的情況下,這個佈局會被解析並載入到root
//如果為false,則會依照root去解析該xml並返回該佈局
//ViewHolder 顧名思義,用作儲存View 即快取製造的View,通過複用減少View的重複建立,提高效率
@Override
public void onBindViewHolder(FruitAdapter.ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}//將每個ViewHolder中的View指定到具體資源
@Override
public int getItemCount() {
return mFruitList.size();
}//返回資料來源的大小/item的個數
}
在Activity中使用
//MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.module_main_activity);
initializeFruits();
RecyclerView recyclerView = findViewById(R.id.rv_fruitList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);//佈局管理器
recyclerView.setLayoutManager(linearLayoutManager);//指定佈局管理器
FruitAdapter adapter = new FruitAdapter(fruitList);//介面卡
recyclerView.setAdapter(adapter);//指定介面卡
}
private void initializeFruits(){//初始化資料
for(int i = 1;i<=2;i++){
fruitList.add(new Fruit("apple",R.drawable.apple_pic));
fruitList.add(new Fruit("banana",R.drawable.banana_pic));
fruitList.add(new Fruit("orange",R.drawable.orange_pic));
fruitList.add(new Fruit("watermelon",R.drawable.watermelon_pic));
fruitList.add(new Fruit("pear",R.drawable.pear_pic));
fruitList.add(new Fruit("grape",R.drawable.grape_pic));
fruitList.add(new Fruit("pineapple",R.drawable.pineapple_pic));
fruitList.add(new Fruit("strawberry",R.drawable.strawberry_pic));
fruitList.add(new Fruit("cherry",R.drawable.cherry_pic));
fruitList.add(new Fruit("mango",R.drawable.mango_pic));
}
}
}
//over
RecyclerView的使用注意
- 資料缺失、遺漏
// 在介面卡中重寫getItemViewType方法
@Override public int getItemViewType(int position) { return position; }
// 禁止ViewHolder複用 (降低效率 不推薦)
// 在onCreateViewHolder製造出ViewHolder後
holder.setIsRecyclable(false);
- 引入支援時的版本問題
代號 | 含義 |
---|---|
Alpha (α) | 預覽版 |
Beta (β) | 測試版 |
RC (Release Candidate) | 最終測試版本 |
越往下越穩定
若出現版本不一致問題
可在app下的build.gradle中新增
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'//指定版本號
}
}
}
}
onCreateViewHolder詳解 //初學者瞭解
- root為null,attachToRoot將失效
- root不為null,若attachToRoot設定為為true,則會給載入的佈局檔案的指定一個父佈局,即root;若attachToRoot設為false,則會將佈局檔案最外層的所有layout屬性進行設定,當該view被新增到父view當中時,這些layout屬性會自動生效
- root不為null時,attachToRoot引數預設為true
返回的view是父容器佈局(不是item佈局的根容器,如例中的root佈局)
item根佈局的寬高屬性生效(item佈局的根容器寬高屬性生效)
新增到父容器中(item佈局已經新增到root中了)
RelativeLayout root = (RelativeLayout) findViewById(R.id.other_layout);
View view = LayoutInflater.from(this).inflate(R.layout.item, root, true);
View view = LayoutInflater.from(this).inflate(R.layout.item, root);
返回R.layout.item頁面的根佈局(item根佈局)
根佈局的寬高屬性生效
未新增到父容器中
RelativeLayout root = (RelativeLayout) findViewById(R.id.other_layout);
View view1 = LayoutInflater.from(this).inflate(R.layout.item, root, false);
返回R.layout.item頁面的根佈局
根佈局的寬高屬性失效(僅寬高屬性失效,其他屬性生效)
未新增到父容器中
View view3 = LayoutInflater.from(this).inflate(R.layout.item, null, false);
View view4 = LayoutInflater.from(this).inflate(R.layout.item, null, true);
View view6 = LayoutInflater.from(this).inflate(R.layout.item, null);
2018/8/15