布局
首先看布局,首先需要一个RecyclerView的View,然后需要一个子布局,子布局需要放在另一个布局文件中,原因是之后的inflate方法需要传入的参数是一个布局文件。
<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处理的是内容和位置关系的逻辑。