需求:
实现将一段文字转化为char列表(有能力可以使用智能分词),然后用户选择自己想要的字或者词,生成新的String
思路:
- 创建列表
- 创建适配器
- 设置滑动监听
- 收集用户选择的文字
- 完毕
实施:
创建布局文件
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingBottom="52dp" />
创建item布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/string_adapter"
android:gravity="center"
android:text="1"
android:textColor="@color/word"
android:textSize="@dimen/word" />
</LinearLayout>
</layout>
适配器只做一件事
数据绑定
holder.binding.text.text = value
RecyclerView处理
这里是关键
// 初始化列表 list.adapter = adapter list.setHasFixedSize(true) list.addItemDecoration(object : RecyclerView.ItemDecoration() { override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { super.getItemOffsets(outRect, view, parent, state) outRect.set(0, 0, 0, 20) } }) list.layoutManager = GridLayoutManager(this@QRCodeScanActivity, 15)
GridLayoutManager不在赘述,类似table布局
这里初始化了一些基本参数之后,我们就需要对整个list做触摸监听了
// 1. 申明一个map 用来保存用户选择的数据
val selectValue = hashMapOf<Int, Char>()
list.addOnItemTouchListener(object : RecyclerView.OnItemTouchListener {
// 用于保存最后一个被划到的界面,防止view在一次滑动时被多次处理
private var lastView: View? = null
/**
* 处理触摸事件
* @return Boolean 返回该触摸是否被拦截
*/
override fun onInterceptTouchEvent(rv: RecyclerView, event: MotionEvent): Boolean {
// 开始分发触摸事件
when (event.action) {
// 用户抬起手指后 置空lastView 防止内存泄漏以及回收拦截(防止第二次点击该view时无法响应事件)
MotionEvent.ACTION_UP -> {
lastView = null
}
// 用户手指滑动的时候 处理事务
MotionEvent.ACTION_MOVE -> {
// 先获取当前手机所在的view
val view = rv.findChildViewUnder(event.x, event.y) ?: return false
// 防止手机在一个view上来回摩擦时抖动
if (view == lastView) {
return false
} else {
lastView = view
}
// 获取当前view的下标
val endIndex = rv.getChildAdapterPosition(view)
// 切换状态
view.isSelected = !view.isSelected
// 开始判断该view是否被选中,未被选中则 选中 并增加颜色
if (view.isSelected) {
// 保存数据
selectValue.put(endIndex, resData[endIndex])
view.findViewById<TextView>(R.id.text).setTextColor(ResUtils.getColor(R.color.word))
} else {
// 移除数据
selectValue.remove(endIndex)
view.findViewById<TextView>(R.id.text).setTextColor(ResUtils.getColor(R.color.white))
}
}
}
return false
}
override fun onTouchEvent(rv: RecyclerView, event: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
})
selectValue存的key就是对应的index,防止重复存入,value就是对应的字符串,最后selectValue.values.forEach { res += it } 将结果累加即可
ps: 如果要根据下标顺序展示 那么利用key去排序即可
技术总结:
要知道滑动监听要监听谁,不能在adapter中监听item
要防止单个view被反复摩擦~
使用map存放时用index当做key 防止重复放入
ps:功能很简单,挺有趣