之前一直都是對RecyclerView死記硬背,然後用完沒多久就忘記了,只記得要添加Adapter,但是會忘記具體內容。於是昨天晚上想了很久理了很久,大概想出了一個記憶的方法,希望自己不要再忘記了嗷。
***************************************
情景:劇場需要一羣學生完成一場表演,然而不能直接和學校聯繫,需要一個第三方的聯繫人去進行安排。
劇場、學校、聯繫人三方的任務分別是:
學校:確定需要學生的什麼資料(Student類)
收集學生資料(initStudent())
把名單給聯繫人(傳入studentList)
劇場:安排表演要用到哪個舞臺(Recyclerview)(一個劇場activity_main可以有很多個舞臺,比如ListView啊、Recyclerview啊)
確定舞臺上的學生是挨個打橫啊還是打豎站位(LinearLayoutManager)
規定學生在自己區域內怎麼站位、道具怎麼擺放(student_item)
聯繫方:和學校交接工作:拿到名單列表(StudentAdapter構造方法)
和劇場交接工作:按照劇場要求確定學生站位和道具擺放方法(重寫OnCreatViewHolder,按照student_item排布)
按名單順序依次把學生和道具安排到不同的位置(重寫OnBindViewHolder)
確定一共有多少人蔘與這次演出(重寫getItemCount)
********************************
具體代碼和情景對應:
※別忘了導入RecyclerView依賴庫!在app->build.gradle中添加
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:recyclerview-v7:26.+'
testCompile 'junit:junit:4.12'
然後把RecyclerView放入activity-main.xml中。導入了依賴庫之後輸入recyclerview是會有提示的,然後按照正常步驟確定id、寬高就可以了
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
下面就是正題啦!
1、確定學生需要的資料(每個學生需要他的名字和一個道具)
新建Student類,字段包括studentName和studentProp。使用構造方法傳入字段數據。
public class Student {
private String studentName;
private int studentProp;
public Student(String studentName, int studentProp){
this.studentName = studentName;
this.studentProp = studentProp;
}
public String getStudentName(){
return studentName;
}
public int getStudentProp(){
return studentProp;
}
}
2、確定一個區域裏學生和道具的站位(RecyclerView子項的佈局)
新建student_item.xml,這裏用左邊放道具,右邊站學生的排布方式。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/student_prop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
<TextView
android:id="@+id/student_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
3、第三方聯繫人的交接和準備工作(RecyclerView的適配器)
新建StudengAdapter類,繼承於RecyclerView.Adapter。
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder> {
}
聯繫人首先要從學校拿到學生的名單,因此使用構造方法傳入名單:
private List<Student> mStudentList;
public StudentAdapter(List<Student> studentList){
mStudentList = studentList;
}
這裏有意思的來了:爲什麼RecyclerView的泛型類要指定爲內部類ViewHolder呢?
我的理解是這樣:假設自己就是那個聯繫人,那麼每次學生上臺的時候,我都要跑過去問一下劇場要這個學生的站位(就算這個學生不小心離開了舞臺1秒鐘,回來之後我也跑過去問一下),每個進入舞臺上的學生我都要去問一次,那麼劇場肯定覺得我煩煩煩煩煩腦子有洞,然而我也要跑來跑去好浪費時間的[這就是一個效率問題]。因此爲了大家的方便,我自己做個小筆記(建立內部類ViewHolder),每個學生第一次進入舞臺的時候我去問一次,然後將他的站位記錄下來,那麼學生再次進入舞臺的時候,我就可以直接從小筆記裏知道他的站位,不用去問劇場了。這裏的ViweHolder就是緩存。
建立內部類ViewHolder:
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView studentProp;
TextView studentName;
public ViewHolder(View view){
super(view);
studentProp = (ImageView) view.findViewById(R.id.student_prop);
studentName = (TextView) view.findViewById(R.id.student_name);
}
}
繼承了RecyclerView.Adapter後,需要實現3個方法:OnCreatViewHolder(),OnBindViewHolder(),getItemCount()。
聯繫人需要知道劇場怎麼安排每個站位裏學生和道具的位置(也就是需要知道RecyclerView的子項佈局student_item)。重寫OnCreatViewHolder,用LayoutInflater加載子項佈局:@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.student_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
聯繫人有了學生名單和站位之後,就把學生和他的道具按順序依次排進站位裏。重寫OnBindVIewHolder:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Student student = mStudentList.get(position);
holder.studentName.setText(student.getStudentName());
holder.studentProp.setImageResource(student.getStudentProp());
}
至於getItemCount(),我們用來返回學生名單長度:
@Override
public int getItemCount() {
return mStudentList.size();
}
那麼到這裏,StudentAdapter也就是聯繫人的分內工作就已經完成啦!接下來就是三方的正式合作了(下面代碼都在MainActivity裏)。
※爲了實現效果,數據源使用initStudent()完成。手動新建很多學生對象,並添加到一個List中:
public void initStudent(){
Student a = new Student("張三", R.drawable.apple);
mStudentList.add(a);
Student b = new Student("李四", R.drawable.banana);
mStudentList.add(b);
Student c = new Student("王五", R.drawable.blackberry);
mStudentList.add(c);
Student d = new Student("趙六", R.drawable.cherry);
mStudentList.add(d);
}
當然不能少了定義一個List:private List<Student> mStudentList = new ArrayList<>();
4、三方的愉快合作:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initStudent(); //收集學生資料
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this); //確定學生之間的相對站位(這裏默認是使用線性豎直排布)
recyclerView.setLayoutManager(layoutManager);
StudentAdapter adapter = new StudentAdapter(mStudentList); //學校把學生名單給聯繫人進行處理
recyclerView.setAdapter(adapter); //聯繫人和劇場進行交接
}
那麼整體的一場活動也就組織完成啦!RecyclerView的整個使用流程就是這樣,來看看結果!