FormLayoutManager首页,里面有github地址
Adapter基类用法
从我首页的文章,大家应该了解到FormLayoutManager实现的是表格每一格的view都会复用,由想可知,我们adapter的数据源的list,存储的是每一格的数据。下面先看一下基类BaseFormAdapter,其他简单的重写我不多说,我说几个关键的地方。
@Override
public int getItemCount() {
return getRowCount() * getColumnCount();
}
再重复一遍,我们复用的是每一格的view,故整个itemCount就是表格的格子数,getRowCount和getColumnCount即使提供给子类来重写描述表格的行数和列数
/**
* 表格的行数
* @return
*/
public abstract int getRowCount();
/**
* 表格的列数
* @return
*/
public abstract int getColumnCount();
接下来看一下我们第一个例子界面TestFormActivity,里面的TestAdapter是直接继承BaseFormAdapter的adapter
@Override
public int getRowCount() {
return 10;
}
@Override
public int getColumnCount() {
return 10;
}
这里都返回10,看一下界面,就知道,这个表格就是简单的一个10x10,数据就是0到99的字符串。其他方法重写跟你平时用RecyclerView的adapter一样,但要注意的是下面的三个方法都是针对一个格子而言的,布局也好,holder也好,设置数据也好。
@Override
public View createView(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_monster_form_item, viewGroup, false);
return view;
}
@Override
public RecyclerView.ViewHolder createViewHolder(View view, int viewType) {
RecyclerView.ViewHolder viewHolder = new ItemHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
ItemHolder holder = (ItemHolder) viewHolder;
holder.tvItem.setText(mList.get(position));
}
BaseHFormAdapter和BaseVFormAdapter
这个两个分别是水平表格和垂直表格的adapter。(水平表格、垂直表格这是我乱取的名字,后面告诉具体是什么)
上面的TestAdapter大家看明白后,接下来就可以认真听了。一般我们的数据源(如后台,数据库给的数据),它不是每一格子代表一个实体的,而是以一行或一列为一个对象实体的,如下两图的表格
左图就是我上面所说的水平表格,在代码里一行就是一个数据Monster对象
右图就是我上面所说的垂直表格,在代码里一行就是一个数据Monster对象
所以才会出现BaseHFormAdapter和BaseVFormAdapter这两个基类,两个基类只是异曲同工,我就抽BaseHFormAdapter来说。
BaseHFormAdapter的出现就是,尽管我们的表格是一个个格子复用,但是你的数据源list还是可以是一个List<Monster>,而不是像TestAdapter那样每个格子的数据都存到list。对于BaseHFormAdapter来说,它的list每个数据对应的就是每一行的数据。说白了,BaseHFormAdapter就是一个帮我们把一行数据转换成表格一格格数据的媒介。
@Override
public int getRowCount() {
return mList.size();
}
BaseHFormAdapter重写了getRowCount的方法(而BaseVFormAdapter当然就是重写getColumnCount,至于为啥,自己想啊,这世界不是你老师,不是什么问题都会公仔画出墙)
getRowCount我们返回的就是list的size了,如上所说,我们的list就是代表每一行数据的列表。而getColumnCount我们就不重写,我们交给继承BaseHFormAdapter的子类来填写。
接下来看一下继承BaseHFormAdapter的MonsterHAdapter
public class MonsterHAdapter extends BaseHFormAdapter<Monster> {
public MonsterHAdapter(Context context) {
super(context);
}
@Override
protected String[] getRowDatas(Monster model) {
return new String[]{model.getName(), model.getAttribute(), model.getLv(), model.getAtk(),
model.getDef(), model.getRace(), model.getType1(), model.getType2()};
}
public MonsterHAdapter(Context context, List<Monster> list) {
super(context, list);
}
@Override
protected View createView(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_monster_form_item, viewGroup, false);
return view;
}
@Override
protected RecyclerView.ViewHolder createViewHolder(View view, int viewType) {
RecyclerView.ViewHolder viewHolder = new ItemHolder(view);
return viewHolder;
}
@Override
protected void setData(RecyclerView.ViewHolder viewHolder, int rowIndex, int columnIndex, String content) {
ItemHolder holder = (ItemHolder) viewHolder;
holder.tvItem.setText(content);
}
@Override
public int getColumnCount() {
return 8;
}
private class ItemHolder extends RecyclerView.ViewHolder {
public TextView tvItem;
public ItemHolder(View itemView) {
super(itemView);
tvItem = itemView.findViewById(R.id.tv_item);
}
}
}
可以看到getColumnCount返回的是8,表明我的表格要显示8列。因为我不知道你要用你实体多少属性来做列,所以这列数根据实际情况来填写。
最关键的一个方法就是getRowDatas,也是提供给大家重写的。看这代码,大家也许get到点了,这个getRowDatas返回的数组就是告诉我们的表格第一列到第八列分别是用实体的那些属性,再看一下BaseHFormAdapter的onBindViewHolder就会更明白了
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int rowIndex = position / getColumnCount();
int columnIndex = position % getColumnCount();
String[] rowDatas = getRowDatas(mList.get(rowIndex));
setData(holder, rowIndex, columnIndex, rowDatas[columnIndex]);
}
在onBindViewHolder里面,我把position转换成该格子对应的行和列,以及该格子对应的文案,一起传到setData。这个时候焦点回到MonsterHAdapter的setData,这个setData方法就是给大家设置每个格控件的属性。
一开始我设计的时候,想getRowDatas这个返回的是一个数组,而每次我们设置格子数据的时候,这里都返回一个数组,而我们每次只用到数组里面一个值。我感觉我应该让getRowDatas返回一个字符串就好了,里面应该用switch/case来告诉表格用实体的那个属性。想着想着,还是数组看起来非常直观地知道每一列分别是那个属性,虽然switch/case也直观,但太大一坨了,你想一想,要是你的表格有30几列,你这switch/case该有多少行。就算我每次返回一个数组,那个数组也很快会被回收,应该也不太会影响性能。其实也如果你是用kotlin的话,我建议的改一下我的BaseHFormAdapter再用,把getRowDatas返回一个字符串,因为kotlin的switch/case非常简洁,而且非常直观地能看出第几列是用那个属性。
这些Adapter基本就当介绍完了。接下来会详细说FormLayoutManager里面的代码了。
敬请期待……