挑戰練習8.8 RecyclerView ViewType


  請在RecyclerView中創建兩類列表項:一般性crime,以及需警方介入的crime。要完成這個挑戰,你需要用到RecyclerView.Adapter的視圖類別功能(view type)。在Crime對象里,再添加一個mRequiresPolice實例變量,使用它並借助getItemViewType(int)方法,確定該加載哪個視圖到CrimeAdapter。

  在onCreateViewHolder(ViewGroup,int)方法里,基於getItemViewType(int)方法返回的ViewType值,需要返回不同的ViewHolder。如果是一般性crime,就仍然使用原始布局;如果是需警方介入的crime,就使用一個帶聯系警方按鈕的新布局。


1.題目要求兩類列表項,如果是需警方介入的crime,就使用一個帶聯系警方按鈕的新布局,因此添加一個新的xml布局文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <LinearLayout
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     android:layout_width="match_parent"
 6     android:layout_height="wrap_content"
 7     android:orientation="vertical"
 8     android:padding="8dp">
 9     <TextView
10         android:id="@+id/crime_title"
11         android:layout_width="match_parent"
12         android:layout_height="wrap_content"
13         android:text="Crime Title"/>
14 
15     <TextView
16         android:id="@+id/crime_date"
17         android:layout_width="match_parent"
18         android:layout_height="wrap_content"
19         android:text="Crime Date"/>
20     <!--挑戰練習:新增一個報警按鈕-->
21     <Button
22         android:id="@+id/require_police"
23         android:layout_width="wrap_content"
24         android:layout_height="wrap_content"
25         android:text="call 110"
26         android:textAllCaps="false"/>
27 </LinearLayout>

2.在Crime對象里,再添加一個mRequiresPolice實例變量,並且為mRequiresPolice添加響應的getter和setter方法

 1 package com.bignerdranch.android.criminalintent.entity;
 2 
 3 import java.util.Date;
 4 import java.util.UUID;
 5 
 6 public class Crime {
 7     private UUID mId;
 8     private String mTitle;
 9     private Date mDate;
10     private boolean mSolved;
11     //題目要求的是否叫警察
12     private boolean mRequiresPolice;
13 
14     public Crime() {
15         this.mId = UUID.randomUUID();
16         this.mDate = new Date();
17     }
18 
19     public UUID getmId() {
20         return mId;
21     }
22 
23     public String getmTitle() {
24         return mTitle;
25     }
26 
27     public void setmTitle(String mTitle) {
28         this.mTitle = mTitle;
29     }
30 
31     public Date getmDate() {
32         return mDate;
33     }
34 
35     public void setmDate(Date mDate) {
36         this.mDate = mDate;
37     }
38 
39     public boolean ismSolved() {
40         return mSolved;
41     }
42 
43     public void setmSolved(boolean mSolved) {
44         this.mSolved = mSolved;
45     }
46 
47     public boolean ismRequiresPolice() {
48         return mRequiresPolice;
49     }
50 
51     public void setmRequiresPolice(boolean mRequiresPolice) {
52         this.mRequiresPolice = mRequiresPolice;
53     }
54 }

3.在CrimeLab中賦值,每10個就是需要警方介入的crime

 1 public  CrimeLab(Context context) {
 2         mCrimes = new ArrayList<>();
 3         for (int i = 0; i < 100; i++) {
 4             Crime crime = new Crime();
 5             crime.setmTitle("Crime #" + i);
 6             crime.setmSolved(i % 2 == 0);
 7             //每隔10個就是需警方介入的crime
 8             crime.setmRequiresPolice(i % 10 == 0);
 9             mCrimes.add(crime);
10         }
11     }

4.在原本CrimeHolder的基礎下新增一個requirePoliceCrimeHolder內部類

 1  //定義一個新的requirePoliceCrimeHolder內部類一個CrimeHolder對應一行列表項,對應布局為 list_item_require_crime
 2     private class requirePoliceCrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
 3         private TextView mTitleTextView;
 4         private TextView mDateTextView;
 5         private Button mRequirePolice;
 6         private Crime mCrime;
 7 
 8         //只要收到一個crime,CrimeHolder就會刷新顯示mTitleTextView和mDateTextView
 9         private void bind(Crime crime) {
10             mCrime = crime;
11             mTitleTextView.setText(mCrime.getmTitle());
12             mDateTextView.setText(mCrime.getmDate().toString());
13         }
14 
15         public requirePoliceCrimeHolder(LayoutInflater inflater,ViewGroup parent) {
16             //首先實例化 list_item_require_crime 布局然后傳給super()即ViewHolder的構造方法*/
17             super(inflater.inflate(R.layout.list_item_crime,parent,false));
18 
19             mTitleTextView = (TextView)itemView.findViewById(R.id.crime_title);
20             mDateTextView = (TextView)itemView.findViewById(R.id.crime_date);
21             mRequirePolice = (Button)itemView.findViewById(R.id.require_police);
22             itemView.setOnClickListener(this);
23         }
24 
25         @Override
26         public void onClick(View v) {
27             Toast.makeText(getActivity(),"Require Police!",Toast.LENGTH_SHORT).show();
28         }
29     }

5.適配器CrimeAdapter,現在多了requirePoliceCrimeHolder,適配器就不能專門用泛型接收CrimeHolder了, 在onCreateViewHolder(ViewGroup,int)方法里,基於getItemViewType(int)方法返回的ViewType值,需要返回不同的ViewHolder。

 1  public class CrimeAdapter extends RecyclerView.Adapter {
 2         private List<Crime> mCrimes;
 3         public CrimeAdapter(List<Crime> crimes) {
 4             mCrimes = crimes;
 5         }
 6         //視圖類別功能
 7         @Override
 8         public int getItemViewType(int position) {
 9             //真不報警
10             if(mCrimes.get(position).ismRequiresPolice()) {
11                 return 1;
12             }else{
13                 return 0;
14             }
15         }
16         @NonNull
17         @Override
18         public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
19             //先創建LayoutInflater
20             LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
21 
22             //判斷上面的i的值判斷使用什么布局,即getItemViewType的返回值
23             if (i == 1)
24                 return new requirePoliceCrimeHolder(layoutInflater, viewGroup);
25             else
26                 return new CrimeHolder(layoutInflater, viewGroup);
27         }
28 
29         //需要綁定數據(上下滑動屏幕)時,就會讀取當前位置並綁定
30         @Override
31         public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
32             if (holder instanceof CrimeHolder) {    //instance,如果左側的對象是右側類的實例,則返回true
33                 Crime crime = mCrimes.get(position);
34                 ((CrimeHolder)holder).bind(crime);
35             }else if (holder instanceof requirePoliceCrimeHolder){
36                 Crime crime = mCrimes.get(position);
37                 ((requirePoliceCrimeHolder)holder).bind(crime);
38             }
39         }
40 
41         @Override
42         public int getItemCount() {
43             return mCrimes.size();
44         }
45     }

6.運行效果:

 

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM