一个基于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~
