淘先锋技术网

首页 1 2 3 4 5 6 7

之前一直都是对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的整个使用流程就是这样,来看看结果!