写点什么

XTableView:一个带侧滑菜单的二维表格控件,kotlin 高阶函数源码讲解

用户头像
Android架构
关注
发布于: 23 小时前

@Override


public void computeScroll() {


if (mScroller.computeScrollOffset()) {


mScrollHelper.notifyScroll(scrollDistance);


mScrollHelper.setScrollX(scrollDistance);


postInvalidate();


}


super.computeScroll();


}


将当前这个 LinearLayout 滚动的最新值去更新全局 scrollX 值,并且通知 ScrollHelper 触发其它 LinearLayout 同步滚动:


public class ScrollHelper {


...


public void notifyScroll(int x) {


for (int i = 0; i < itemViewsMap.size(); i++) {


itemViewsMap.get(itemViewsMap.keyAt(i)).notifyScroll(x);


}


}


...


}


当然,记得在 View 被销毁的时候清除集合数据,避免泄露

[](

)如何实现惯性滚动?


主要借助于 Scrollerfling 方法,fling 可以让 View 在滑动到某个位置之后以一定的速度惯性滚到一段距离。因此在收到 MotionEvent.ACTION_UP 事件时(即手指抬起时),将惯性滚动前的初始 ScrollX 值作为 fling 的起始参数,然后依旧是在 computeScroll 方法里面获取最新滚动到的 ScrollX 值去同步给其他 LinearLayout,实现所有横向列表整体惯性。

[](

)如何处理侧滑与横向列表的滑动冲突?


这里的侧滑实现是基于 SwipeRecyclerView 这个库的基础上进行修改,所以这里自定义一个 RecyclerView 继承于 SwipeRecyclerView 重写其 onInterceptTouchEvent 方法,每次收到 MotionEvent.ACTION_MOVE 事件的时候,判断当前内容区是否滑到了最左侧界线,分别做如下处理:


如果此时位于最左侧界线,判断当前手势是左滑还是右滑,如果是右滑,那就通过 super.onInterceptTouchEvent(e)交由 SwipeRecyclerView 去处理侧滑逻辑,如果是左滑,则需要 return true 拦截事件,然后在 onTouchEvent 中做横向滚动处理。 如果当前不在左侧界线,说明无论左滑还是右滑,横向列表皆有滑动的空间,同样 return true 拦截事件交由 onTouchEvent 中做横向滚动处理。


[](


)如何使用




在项目根目录的 b


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


uild.gradle 添加:


allprojects {


repositories {


...


maven { url 'https://jitpack.io' }


}


}


在项目的 build.gradle 添加如下依赖:


implementation 'com.github.GitHubZJY:XTableView:v1.0.0'

[](

)1.在 xml 中引用 XTableView


<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">


</com.zjy.xtableview.XTableView>

[](

)2.在代码中初始化 XTableView


ITableView vTableView = findViewById(R.id.table_view);


//设置是否支持长按拖动列表项


vTableView.setLongPressDragEnable(true);


//设置是否支持侧滑菜单


vTableView.setSwipeEnable(true);

[](

)3.绑定数据


绑定数据的设计灵感来自于 RecyclerView 的 adapter 设计,与数据相关的操作均通过 XTableAdapter 作为中间者来进行:

[](

)1.自定义一个 adapter 继承于 XTableAdapter ,通过实现 adapter 的方法,自定义表格样式。XTableAdapter 的各个方法作用如下:


onBindHeader 创建列头部视图 onCreateTableItem 创建每一个单元格的视图 onBindTableItem 绑定每一个单元格的视图数据 onCreateRowHeader 创建每一行的头部视图 onBindRowHeader 绑定每一行的头部视图数据


public class CustomTableAdapter extends XTableAdapter<String, TableRowModel<TableRowHeaderModel, TableRowCellModel>>{


public CustomTableAdapter(Context context) {


super(context);


}


@Override


public View onBindHeader(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);


}


}

[](

)2.通过 adapter 的 bindData 绑定自定义数据源.

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
XTableView:一个带侧滑菜单的二维表格控件,kotlin高阶函数源码讲解