Bootstrap

关于RecyclerView中嵌套EditText引发的问题总结

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的问题的几种解决方法

;