RecyclerView详解(一)

布局

首先看布局,首先需要一个RecyclerView的View,然后需要一个子布局,子布局需要放在另一个布局文件中,原因是之后的inflate方法需要传入的参数是一个布局文件。
RecyclerView详解(一)

  <android.support.v7.widget.RecyclerView
        android:id="@+id/id_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

子布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv_item"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center" />
</FrameLayout>

看活动中的代码

public class MainActivity extends AppCompatActivity {
    private HomeAdapter mHomeAdpater;
    private List<String> mList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView mRecyclerView = findViewById(R.id.id_recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        initData();
        mHomeAdpater = new HomeAdapter(this,mList);
        mRecyclerView.setAdapter(mHomeAdpater);
    }
    private void initData(){
        mList = new ArrayList<String>();
        for (int i = 0; i < 20;i++){
            mList.add(i+"");
        }
    }
}

首先活动中有两个私有成员变量,一个是适配器,一个是字符串列表。列表用来存储初始化时需要的数据,而适配器主要的作用是把数据填充到整个RecyclerView中,简单理解适配器将数据和RecyclerView中的每一个item一一对应。

onCreate方法传入一个参数Bundle savedInstanceState,里面存储了之前保存的一些状态和数据,onCreate能据此做一些恢复的工作。setContentView作用是把布局文件填充到当前活动中去。这里要注意findViewById方法默认是当前活动来调用的,因此findViewById只能找到当前活动拥有的控件,否则会返回null。这里,mRecyclerView.setLayoutManager(new LinearLayoutManager(this));为RecyclerView设置了一个布局管理器,这个布局管理器是线性布局的,这里的布局是条目的布局,可以用布局管理器给布局进行设置。

适配器的构造函数new HomeAdapter(this,mList)这里传入两个参数,一个是上下文,第二个是要填充的数据,这里的上下文显然指的就是主活动所在的环境。然后使用mRecyclerView.setAdapter(mHomeAdpater);将适配器传入。这样RecyclerView的基本设置就完成了。

适配器

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {
    private List<String> mList;
    private Context mContext;
   public HomeAdapter(Context mContext,List<String> mList){
       this.mContext = mContext;
       this.mList = mList;
   }
    @Override
    public MyViewHolder onCreateViewHolder( ViewGroup viewGroup, int i) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(
                R.layout.item_recycler,viewGroup,false));
        return holder;
    }
   @Override
    public void onBindViewHolder( final MyViewHolder holder,final int i) {
        holder.tv.setText(mList.get(i));
    }
    @Override
    public int getItemCount() {
        return mList.size();
    }
     class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tv = itemView.findViewById(R.id.tv_item);
        }
    }
}

首先我们自定义的适配器继承自RecyclerView.Adapter,这显然是一个静态的类,这个类需要传递一个泛型,这个泛型的类型就是我们自定义的ViewHolder。首先我们的适配器肯定需要自己的环境和数据,因此有私有成员Context和List,然后需要一个构造方法来传递这两个参数。继承RecyclerView.Adapter需要重写3个方法。首先在onCreateViewHolder中,需要传入两个参数,viewGroup很好理解,就是所有条目的集合,i就是条目所在的位置。然后需要返回一个我们自定义的ViewHolder,这个ViewHolder的构造函数需要传递的是一个布局。我们将填充好的布局传入,LayoutInflater的from方法传入的环境就是之前传入的上下文,即主活动所在上下文。inflate方法传入三个参数,第一个参数是子项布局,第二个参数是顶层容器View Group, 由于子项布局的文件对应的不是主活动的上下文,因此第三个参数只能填false。再看自定义的MyViewHolder,构造方法中传入了一个View,这里的View显然指的是子项布局的整个View,这里的holder处理逻辑很简单,直接保存子项布局中的id为tv_item的TextView控件。然后在onBindViewHolder方法中,将数据填入到TextView中。简单理解,onBindViewHolder处理的是内容和位置关系的逻辑。

上一篇:python如何在列表、对象、集合中根据条件筛选数据


下一篇:《APP》团队冲刺第二阶段 九