表格是自打我进公司之后就使用的控件,起初使用的是ScrollablePanel,从一开始的被花式吊打,到后期的熟练使用。 php
大佬写的控件确实给个人工做带来了极大的方便,不过仍是有些问题存在:java
在我深刻学习RecyclerView
之后,想能不能只用一层RecyclerView
,借助LayoutManager
实现,写着写着,发现该思路可行,并实现了一款基于一个RecyclerView
的表格控件TableView
,先看一下效果:android
Github地址:github.com/mCyp/Orient…git
TableView具备以下特色:github
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.fragment.table.TableFragment">
<com.orient.me.widget.rv.adapter.TableView android:id="@+id/tb" android:layout_width="match_parent" android:layout_height="match_parent"/>
</FrameLayout>
复制代码
在展现代码以前,了解一下TableView中的主要函数:ide
方法 | 描述 |
---|---|
setTitle(boolean isLeftOpen, boolean isTopOpen) |
左侧或者上侧的悬浮标题是否显示,默认显示 |
setModeAndValue(int mode, int w, int h) |
mode-表格模式、w-具体的宽度\一行容纳的单元格数、h-具体的高度\一列容纳的单元格数 |
这个setTitle(boolean isLeftOpen, boolean isTopOpen)
有什么做用呢?为了确保表格的每个单元格的长度和宽度都同样(子视图能够在横纵方向上占有多个单元格),宽和高都使用两种方式:函数
因此宽高各有两种,模式的数量 = 2 * 2,总共有:布局
Mode模式 | w的说明 | h的说明 |
---|---|---|
TableLayoutManager.MODE_A |
父布局一行容纳的单元格数 | 父布局一列容纳的单元格数 |
TableLayoutManager.MODE_B |
单元格宽度 | 单元格高度 |
TableLayoutManager.MODE_C |
父布局一行容纳的单元格数 | 单元格高度 |
TableLayoutManager.MODE_D |
单元格宽度 | 父布局一列容纳的单元格数 |
代码:post
// if use butterknife
// or use findViewById
@BindView(R.id.tb)
TableView mTable;
// 默认为 TableLayoutManager.MODE_A, 4, 8
mTable.setModeAndValue(TableLayoutManager.MODE_A, 6, 8);
复制代码
实现ICellItem
接口:性能
public class TableCell implements ICellItem {
private String name;
private String value;
private int type;
private int row;
private int col;
private int widthSpan;
private int heightSpan;
//... 省略构造函数和Get Set方法
@Override
public int getRow() {
return row;
}
@Override
public int getCol() {
return col;
}
@Override
public int getWidthSpan() {
return widthSpan;
}
@Override
public int getHeightSpan() {
return heightSpan;
}
}
复制代码
private TableAdapter<TableCell> mAdapter;
protected void initWidget(View root) {
// 假设在这个方法中初始化
mTable.setAdapter(mAdapter = new TableAdapter<TableCell>(new ArrayList<>()) {
@Override
public int getItemLayout(TableCell tableCell, int pos) {
// ... 返回子视图布局文件
// 支持多类型
return R.layout.table_cell_content_item;
}
@Override
public BaseAdapter.ViewHolder<TableCell> onCreateViewHolder(View root, int itemType) {
// itemType是子视图布局文件
// 根据布局返回具体的ViewHolder
return new ContentHolder(root);
}
});
}
// 具体的ViewHolder
class ContentHolder extends BaseAdapter.ViewHolder<TableCell>{
TextView mContent;
public ContentHolder(View itemView) {
super(itemView);
mContent = itemView.findViewById(R.id.tv_name);
}
@Override
protected void onBind(TableCell tableCell) {
mContent.setText(tableCell.getValue());
}
}
复制代码
若是TableView
使用的模式是Mode_A
、Mode_C
和Mode_D
,须要再从新测量:
mTable.post(() -> mTable.reMeasure());
复制代码
总的来讲,TableView
的核心是TableLayoutManager
,也就是RecyclerView
中的LayoutManager
,相似于能够随时横纵向切换的GridLayoutManager
,若是各位同窗对TableView
感兴趣,我将会在后续的文章深刻原理。
探索不易,若是以为【Orient-Ui】不错,欢迎Star或者提出问题,年前的最后一篇技术文章啦,你们加油~
深刻原理以前,建议复习RecyclerView的原理:
《抽丝剥茧RecyclerView - 化整为零》
《抽丝剥茧RecyclerView - LayoutManager》