Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 当RecyclerView在一行中获得两个相同的对象时,它会移动;照相机“;对于第二个,将前一个留在视图之外;“以上”;_Android_Kotlin_Android Recyclerview_Listadapter - Fatal编程技术网

Android 当RecyclerView在一行中获得两个相同的对象时,它会移动;照相机“;对于第二个,将前一个留在视图之外;“以上”;

Android 当RecyclerView在一行中获得两个相同的对象时,它会移动;照相机“;对于第二个,将前一个留在视图之外;“以上”;,android,kotlin,android-recyclerview,listadapter,Android,Kotlin,Android Recyclerview,Listadapter,在片段中: @AndroidEntryPoint class DrillerFragment : Fragment(R.layout.cardstack_layout), CardStackListener { private val viewModel: DrillerViewModel by viewModels() private lateinit var currentWord :Word private val drillerAdapter = Driller

在片段中:

@AndroidEntryPoint
class DrillerFragment : Fragment(R.layout.cardstack_layout), CardStackListener {

    private val viewModel: DrillerViewModel by viewModels()
    private lateinit var currentWord :Word
    private val drillerAdapter = DrillerAdapter()
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = CardstackLayoutBinding.bind(view)
        viewModel.getLivedataList().observe(viewLifecycleOwner) {
                    drillerAdapter.submitList(it)
                    Log.d(TAG, "drlr workWorkList.size = " + it.size)
                }
        val drillerLayoutManager = CardStackLayoutManager(requireContext(), this)
        binding.apply {
        cardStackView.apply {
            layoutManager = drillerLayoutManager
            adapter = drillerAdapter
            itemAnimator = null // ХЗ НАДО ЛИ
        }
    }
    viewModel.get4words()
}

override fun onCardSwiped(direction: Direction?) {
        if (direction == Direction.Bottom) {
            currentWord.shown = false
            viewModel.update(currentWord)
        }
        viewModel.removeAndAddWord(currentWord)
        Log.d(TAG, currentWord.foreign + " is removed. (drlr)")
    }
override fun onCardAppeared(view: View?, position: Int) {
    currentWord = drillerAdapter.getWordAt(position)
    Log.d(TAG, "onCardAppeared: " + currentWord.foreign + " IS NOW currentWord, position in adapter - " + position + " (drlr)")
}
override fun onCardDisappeared(view: View?, position: Int) {
    currentWord = drillerAdapter.getWordAt(position)
    Log.d(TAG, "onCardDisappeared: " + currentWord.foreign + " IS NOW currentWord, position in adapter - " + position + " (drlr)")
}
视图模型代码:

    class DrillerViewModel @ViewModelInject constructor(
    private val wordDao: WordDao,
) : ViewModel() {
    var mList = ArrayList<Word>()
    val mLivedataList = MutableLiveData<List<Word>>()
    val m4words = wordDao.get4wordsRx()
    val m1word = wordDao.get1wordRx()
    val composite = CompositeDisposable()


    fun getLivedataList(): LiveData<List<Word>> {
        return mLivedataList
    }

    fun get4words() {
        m4words.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object :
                SingleObserver<List<Word>> {
                override fun onSubscribe(d: Disposable) {
                    composite.add(d)
                }

                override fun onSuccess(t: List<Word>) {
                    mList.addAll(t)
                    mLivedataList.value = mList
                }

                override fun onError(e: Throwable) {
                    // empty
                }

            })
    }

    fun removeAndAddWord(word: Word) {
        mList = ArrayList<Word>(mList)
        mList.remove(word)
        Log.d(TAG, "(drlr) removeAndAddWord: mList.size =  " + mList.size)
        m1word.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : SingleObserver<Word> {
                override fun onSubscribe(d: Disposable) {
                    composite.add(d)
                }

                override fun onSuccess(t: Word) {
                    mList.add(t)
                    mLivedataList.value = mList
                    Log.d(TAG, "(drlr) removeAndAddWord called, now mList contains: ")
                    mList.forEach { item -> Log.d(TAG, "(drlr) " + item.foreign) }
                }

                override fun onError(e: Throwable) {
                    // empty
                }

            })
    }

    fun update(word: Word) = viewModelScope.launch {
        wordDao.update(word)
    }
}
class-drillServiceWModel@ViewModelInject构造函数(
二等兵val wordDao:wordDao,
):ViewModel(){
var mList=ArrayList()
val mLivedataList=MutableLiveData()
val m4words=wordDao.get4wordsRx()
val m1word=wordDao.get1wordRx()
val composite=CompositeDisposable()
fun getLivedataList():LiveData{
返回多重催化剂
}
有趣的get4words(){
m4words.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(对象:
单一观察者{
覆盖订阅的乐趣(d:一次性){
添加(d)
}
成功时覆盖乐趣(t:列表){
mList.addAll(t)
mLivedataList.value=mList
}
覆盖有趣的错误(e:可丢弃){
//空的
}
})
}
趣味removeAndAddWord(word:word){
mList=阵列列表(mList)
mList.remove(word)
Log.d(标记“”(drlr)removeanddword:mList.size=“+mList.size”)
m1word.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(对象:SingleObserver){
覆盖订阅的乐趣(d:一次性){
添加(d)
}
成功时覆盖乐趣(t:Word){
列表添加(t)
mLivedataList.value=mList
Log.d(标记“”(drlr)removeanddword已调用,现在mList包含:)
mList.forEach{item->Log.d(标记,“(drlr)”+item.foreign)}
}
覆盖有趣的错误(e:可丢弃){
//空的
}
})
}
有趣的更新(word:word)=viewModelScope.launch{
更新(word)
}
}
(CardStackView本身必须始终包含4个单词,它是从数据库随机获取的,有时它可以获取相同的单词,这是一个学习单词的应用程序。)

我注意到:

  • 当一行中有两个具有类似值的项时,在removeAndAdd()方法上,以一种奇怪的方式,位于位置0的项保留在recycleView列表中,并且recycling视图被移动到位置1,在视图范围之外的上方留下零项
  • 当两个连续的单词完全相同时,就会发生这种情况。当顶部位置被其中一个占据,第二个位置在其正下方时,视图立即移动到第二个位置,第一个位置在视图外保持“较高”(但仍在列表中,好像在适配器中被考虑,因为如果“阻塞”消失(即下一个单词完全不同),然后视图返回到第一个缺少的项
  • 底部的字越少,适配器位置从0移动到1的频率就越高。如果向下滑动(请参见onswip()),则Word.Showed将变为false,并且该字不会再次出现(get1word方法仅从底部获取show=true的字),然后包含的字越少,工作列表中的重复次数越多,这种“堵塞”就越多。CardStackView点击底部,屏幕变为空白,尽管列表中有未移动的单词
  • 我无法理解如何治愈它。谢谢你的帮助

    这是适配器代码:

    class DrillerAdapter() : ListAdapter<Word, DrillerAdapter.DrillerViewHolder>(DrillerDiff()) {
    
    
        inner class DrillerViewHolder(private val binding: CardstackItemBinding) :
            RecyclerView.ViewHolder(
                binding.root
            ) {
    
            init {
                binding.apply {
                    root.setOnClickListener {
                        val position = adapterPosition
                        if (position != CardStackView.NO_POSITION) {
                            tvNativ.visibility = View.VISIBLE
                        }
                    }
                }
            }
    
            fun bind(word: Word) {
                binding.apply {
                    tvForeign.text = word.foreign
                    tvNativ.text = word.nativ
                    tvNativ.visibility = View.INVISIBLE
                }
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DrillerViewHolder {
            val binding = CardstackItemBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
            return DrillerViewHolder(binding)
        }
    
        override fun onBindViewHolder(holder: DrillerViewHolder, position: Int) {
            val currentItem = getItem(position)
            holder.bind(currentItem)
        }
    
        fun getWordAt(position: Int): Word {
            return getItem(position)
        }
    
        class DrillerDiff : DiffUtil.ItemCallback<Word>() {
            override fun areItemsTheSame(oldItem: Word, newItem: Word) =
                oldItem.id == newItem.id
    
            override fun areContentsTheSame(oldItem: Word, newItem: Word) =
                oldItem == newItem
        }
    
    }
    
    class DrillerAdapter():ListAdapter(DrillerDiff()){
    内部类DrillServiceWholder(私有val绑定:CardstackItemBinding):
    RecyclerView.ViewHolder(
    绑定根
    ) {
    初始化{
    应用{
    root.setOnClickListener{
    val位置=适配器位置
    if(位置!=CardStackView.无位置){
    tvNativ.visibility=View.VISIBLE
    }
    }
    }
    }
    趣味绑定(word:word){
    应用{
    tvForeign.text=word.foreign
    tvNativ.text=word.nativ
    tvNativ.visibility=View.INVISIBLE
    }
    }
    }
    重写CreateViewHolder(父级:ViewGroup,viewType:Int):DrillServiceWholder{
    val绑定=CardstackItemBinding.充气(
    LayoutFlater.from(父上下文),
    父母亲
    假的
    )
    返回钻孔机(装订)
    }
    覆盖BindViewHolder(holder:DrillServiceWholder,位置:Int){
    val currentItem=getItem(位置)
    持有者绑定(当前项)
    }
    fun getWordAt(位置:Int):单词{
    返回项目(位置)
    }
    类DrillerDiff:DiffUtil.ItemCallback(){
    覆盖趣味项目相同(旧项目:Word,新项目:Word)=
    oldItem.id==newItem.id
    覆盖相同的内容(旧项:Word,新项:Word)=
    oldItem==newItem
    }
    }