EditText 在 notifyDataSetChanged() 后失去焦点

EditText lose focus after notifyDataSetChanged()

我尝试使用这个答案

editText.setOnFocusChangeListener { editText, focus ->
                    testDataObject.fieldHasFocus = focus
                }

但它不起作用,因为 android 在 notifyDataSetChanged 之后清除了焦点,并且焦点始终为 false。我可能错误地实施了答案。 还有这个 但这也行不通

我也试过做个延时然后定焦

      GlobalScope.launch(Dispatchers.Main) {
           delay(1000)
           editText.requestFocus()
      }

但是效果很差

完整代码 github

适配器

package com.`package`.viewpagertest

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import by.lwo.viewpagertest.R
import by.lwo.viewpagertest.databinding.HolderTestBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class ViewPagerAdapter(var list: List<TestDataObject>) : RecyclerView.Adapter<ViewPagerAdapter.TestHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.holder_test, parent, false)
        val binding: HolderTestBinding = DataBindingUtil.bind(view)!!
        return TestHolder(binding)
    }

    override fun onBindViewHolder(holder: TestHolder, position: Int) {
        holder.bind(list[position])
    }

    override fun getItemCount(): Int = list.size

    fun updateData(items: List<TestDataObject>) {
        list = items
        notifyDataSetChanged()
    }

    inner class TestHolder(private val binding: HolderTestBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(testDataObject: TestDataObject) {
            binding.apply {
                titleTv.text = testDataObject.titleText
                textTv.text = testDataObject.infoText
                editText.setOnFocusChangeListener { editText, focus ->
                    testDataObject.fieldHasFocus = focus
                }
                if(testDataObject.fieldHasFocus) editText.requestFocus()
//                GlobalScope.launch(Dispatchers.Main) {
//                    delay(1000)
//                    editText.requestFocus()
//                }
            }
        }
    }

}

data class TestDataObject(val titleText: String = "", val infoText: String = "", var fieldHasFocus: Boolean = false)

主要活动

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import by.lwo.viewpagertest.databinding.ActivityMainBinding
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.random.Random

class MainActivity : AppCompatActivity() {

    lateinit var binding: ActivityMainBinding
    private var adapter: ViewPagerAdapter? = null
    val testList: MutableList<TestDataObject> = emptyList<TestDataObject>().toMutableList()

    private val _testLiveData = MutableLiveData<Event<List<TestDataObject>>>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setDataToList()
        setAdapter()
        constantlyUpdateList()

        _testLiveData.observeEvent(this) {
            adapter?.updateData(it)
            constantlyUpdateList()
        }


    }

    private fun constantlyUpdateList() {
        lifecycleScope.launch {
            delay(5000)
            setDataToList()
            _testLiveData.value = Event(testList)
        }
    }

    private fun setDataToList() {
        testList.clear()
        repeat(6) {
            testList.add(
                TestDataObject(
                    titleText = "title for page $it ${Random.nextInt()}",
                    infoText = "infoText for page $it ${Random.nextInt()}"
                )
            )
        }
    }

    private fun setAdapter(){
        binding.apply {
            adapter = ViewPagerAdapter(testList)
            viewPager.adapter = adapter
            binding.viewPager.offscreenPageLimit = testList.size
        }
    }
}

你需要在片段中设置

viewPagerAdapter.setHasStableIds(true)

片段

private fun setAdapter(){
        binding.apply {
            val viewPagerAdapter = ViewPagerAdapter(testList)
            viewPagerAdapter.setHasStableIds(true)
            viewPager.adapter = viewPagerAdapter
            (binding.viewPager.getChildAt(0) as RecyclerView).itemAnimator = null // Add if the item is blinking
        }
    }

并在您的 ViewPagerAdapter 中覆盖 getItemId

适配器

override fun getItemId(position: Int) = position.toLong()