一个基于RecyclerView+Scroller实现的二维表格组件,同时支持侧滑菜单、拖动调整列表顺序、刷新动画等拓展功能。
A two-dimensional table view, base on recyclerview, both support to side slide menu、drag item、refresh animation and more.
- 基于RecyclerView实现,可复用视图
- 支持自定义数据源类型、表头及单元格样式
- 支持列表Item侧滑菜单
- 支持拖拽变换顺序
- 支持默认刷新动画
- 支持设置点击头部监听
- 支持AndroidX
在项目根目录的build.gradle添加:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
在项目的build.gradle添加如下依赖:
implementation 'com.github.GitHubZJY:XTableView:v1.0.0'
<com.zjy.xtableview.XTableView
android:id="@+id/table_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:swipeLayout="@layout/table_swipe_menu_layout"
app:headerHeight="50dp"
app:rowHeight="80dp"
app:cellWidth="130dp"
app:notifyAnim="true">
</com.zjy.xtableview.XTableView>
ITableView vTableView = findViewById(R.id.table_view);
//设置是否支持长按拖动列表项
vTableView.setLongPressDragEnable(true);
//设置是否支持侧滑菜单
vTableView.setSwipeEnable(true);
绑定数据的设计灵感来自于RecyclerView的adapter设计,与数据相关的操作均通过 XTableAdapter
作为中间者来进行.
onBindTableHeader 绑定左上角表头视图
onBindColumnHeader 绑定(除表头外的)普通列头部视图
onCreateTableItem 创建每一个单元格的视图
onBindTableItem 绑定每一个单元格的视图数据
onCreateRowHeader 创建每一行的头部视图
onBindRowHeader 绑定每一行的头部视图数据
public class CustomTableAdapter extends XTableAdapter<String, TableRowModel<TableRowHeaderModel, TableRowCellModel>>{
public CustomTableAdapter(Context context) {
super(context);
}
@Override
public View onBindTableHeader(String s) {
TextView cellTv = new TextView(getContext());
cellTv.setTextColor(getColor(R.color.table_view_second_txt_color));
cellTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
cellTv.setGravity(Gravity.START|CENTER);
cellTv.setText(s);
return cellTv;
}
@Override
public View onBindColumnHeader(int position, String t) {
TextView cellTv = new TextView(getContext());
cellTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
cellTv.setGravity(Gravity.CENTER);
cellTv.setText(t);
return cellTv;
}
@Override
public View onCreateTableItem(int position) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.table_item_cell_layout, null);
TextView cellTv = view.findViewById(R.id.cell_tv);
cellTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
cellTv.setGravity(Gravity.CENTER);
return view;
}
@Override
public void onBindTableItem(int position, View view, TableRowModel<TableRowHeaderModel, TableRowCellModel> rowModel) {
final TableRowCellModel cellModel = rowModel.getRowData().get(position);
TextView cellTv = view.findViewById(R.id.cell_tv);
cellTv.setTextColor(cellModel.isRise() ?
getColor(R.color.table_view_rise_txt_color)
: getColor(R.color.table_view_fall_txt_color));
cellTv.setText(cellModel.getContent());
cellTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), cellModel.getContent(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public View onCreateRowHeader(int position) {
return LayoutInflater.from(getContext()).inflate(R.layout.table_item_title_layout, null);
}
@Override
public void onBindRowHeader(int position, View view, TableRowModel<TableRowHeaderModel, TableRowCellModel> rowModel) {
TextView vTitle = view.findViewById(R.id.title_tv);
TextView vDetail = view.findViewById(R.id.detail_tv);
String title = rowModel.rowHeader.getTitle();
String detail = rowModel.rowHeader.getDetail();
vTitle.setText(TextUtils.isEmpty(title) ? "" : title);
vDetail.setText(TextUtils.isEmpty(detail) ? "" : detail);
}
}
/**
* 更新表格数据
* @param header 左上角的表头数据
* @param columnHeader 列头部数据集合
* @param tableData 每一行的数据集合
*/
public void bindData(T header, List<T> columnHeader, List<H> tableData)
vTableView.setTableAdapter(adapter);
数据变更也是通过adapter对象来进行:
如果是所有数据替换,可调用 bindData
方法设置新的数据,然后通过 notifyDataSetChanged
进行更新.
如果是单条数据刷新,可调用 notifyItemData(int position, H data)
进行更新,position是对应的下标,data为新的数据.
如果是单条数据插入,可调用 notifyInsertData(int position, H data)
进行更新,position是对应的下标,data为新的数据.
vTableView.setTableListener(new XTableListener() {
@Override
public void clickSwipeMenu(int position) {
//点击菜单
...
}
@Override
public void onItemMove(int fromPos, int toPos) {
//拖拽Item
...
}
@Override
public void onColumnHeaderItemClick(int position) {
Toast.makeText(MainActivity.this, "点击了第" + position + "列的头部", Toast.LENGTH_SHORT).show();
//点击某一列头部之后对列表数据进行重排序
..
}
});
目前支持点击侧滑菜单、拖拽列表项、点击列头部的监听回调,例如实现根据某列进行排序的需求可以在 onColumnHeaderItemClick
里面进行
本库也提供了LayoutManager的一些配置,例如: setReverseLayout
、 setStackFromEnd
、 scrollToPosition
、 scrollToPositionWithOffset
等,后续会再根据需要进行扩充.
SwipeRecyclerView
侧滑和拖拽是在SwipeRecyclerView这个库的基础上修改,是一个基于RecyclerView拓展得不错的组件。本库的自定义样式和数据类型基于适配器的模式设计,后续会继续更新,提升组件的定制性和可拔插性,欢迎issue和star~