RecyclerView のネストされた EditText によって引き起こされる問題の概要

1. データ障害

最近WebベースのRecycelrViewエディターを開発しているのですが、多重化によりスクロール時のデータの混乱が起こるという問題がRecyclerviewありましたEdittextRecyclerview

処理方法は次のとおりです。

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. エディットテキストにフォーカスが当たっているため、スライドがスムーズではありません

recyclerViewセットする

android:descendantFocusability="beforeDescendants"

参考記事は次のとおりです:
EditText がフロッピー ディスクによってブロックされ、キーボード ポップアップ レイアウトが上に移動しない問題を解決する
RecyclerView の Edittext の問題に対するいくつかの解決策

おすすめ

転載: blog.csdn.net/weixin_44710164/article/details/126387801