[Android UI]RecyclerView使用的記憶方法

之前一直都是對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的整個使用流程就是這樣,來看看結果!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章