1.数据错乱
最近在开发一个基于RecycelrView
的编辑器, Recyclerview
中包含Edittext
在滚动时会发生数据混乱的问题,之所以数据混乱就是因为Recyclerview
的复用导致的。
处理方式为:
在onBindViewHolder中通过在适当的时机添加或移除Edittext的TextChangedListener来处理数据错乱的问题。这个适当的时机就是选在Edittext获得焦点的时候添加监听器,失去焦点的时候再移除监听器,这样可以保证数据的正确性。
override fun convert(helper: BaseViewHolder, item: LongTextModel) {
val adapter = getAdapter()
val list = adapter?.data
val img = helper.getView<ImageView>(R.id.imgCover)
val imgDescribe = helper.getView<EditText>(R.id.imgDescribe)
val etContent = helper.getView<EditText>(R.id.etContent)
etContent.setText(item.edit)
imgDescribe.setText(item.imgDescribe)
val contentWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val value = s.toString()
item.edit = value
}
}
val describeWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val value = s.toString()
item.imgDescribe = value
}
}
etContent.setOnFocusChangeListener{_,hasFocus->
if (hasFocus){
etContent.addTextChangedListener(contentWatcher)
}else{
etContent.removeTextChangedListener(contentWatcher)
}
}
imgDescribe.setOnFocusChangeListener{_,hasFocus->
if (hasFocus){
imgDescribe.addTextChangedListener(describeWatcher)
}else{
imgDescribe.removeTextChangedListener(describeWatcher)
}
}
}
2.关于edittext
无法复制的问题
只需要在重写onViewAttachedToWindow
方法然后设置isEnabled
override fun onViewAttachedToWindow(holder: BaseViewHolder) {
super.onViewAttachedToWindow(holder)
val imgDescribe = holder.getView<EditText>(R.id.imgDescribe)
val etContent = holder.getView<EditText>(R.id.etContent)
imgDescribe.isEnabled = false
imgDescribe.isEnabled = true
etContent.isEnabled = false
etContent.isEnabled = true
}
3. 关于RecyclerView嵌套EditText,唤起键盘时被遮挡
修改前:
修改后:
window.decorView.viewTreeObserver.addOnGlobalLayoutListener {
// 除了软键盘以外的可见区域
val rect = Rect()
window.decorView.getWindowVisibleDisplayFrame(rect)
// 计算出剩余高度: 除了状态栏高度、topBar高度、bottomBar高度、键盘高度的剩余高度
var invisibleHeight: Int = (rect.bottom
- ScreenUtils.getStatusBarHeight(this@EditorLongTextActivity) // 状态栏高度
- 44.dip2px //标题栏
- 44.dip2px //底部菜单栏 R.id.bottomLayout 即图中 图片添加按钮的整个容器的高度
)
if (BarUtils.isNavBarVisible(window)) {
invisibleHeight -= navBarHeight
}
//对尾部 最后一条数据进行修改即可
var currentIndex = mAdapter.data.size - 1
mAdapter.data.forEachIndexed { index, longTextModel ->
if (longTextModel.focus) {
currentIndex = index
}
}
// 计算出所点击的图片描述的EditText距离RecyclerView顶部的距离
val etDescView: View? =
binding.recyclerView.layoutManager?.findViewByPosition(currentIndex)
if (etDescView != null) {
val focusViewTop: Int = etDescView.top
val itemHeight: Int = etDescView.height
val differ = focusViewTop + itemHeight - invisibleHeight
if (differ > 0) {
binding.recyclerView.scrollBy(0, differ)
}
}
}
4. 因为edittext获取焦点导致滑动不流畅
在recyclerView
中设置
android:descendantFocusability="beforeDescendants"
参考文章来源于:
解决EditText被软盘遮挡和键盘弹出布局不上移
关于RecyclerView中包含Edittext的问题的几种解决方法