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()
我尝试使用这个答案
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()