Clear callbacks on CandidateViewHolder once recycled

hopefully fixes some weird crash
This commit is contained in:
Rocka 2025-11-09 02:10:26 +08:00
parent 77bcd44b62
commit 4a955a1959
No known key found for this signature in database
GPG Key ID: 28031158FFDD6853
5 changed files with 41 additions and 11 deletions

View File

@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* SPDX-FileCopyrightText: Copyright 2021-2024 Fcitx5 for Android Contributors
* SPDX-FileCopyrightText: Copyright 2021-2025 Fcitx5 for Android Contributors
*/
package org.fcitx.fcitx5.android.input.candidates.expanded.window
@ -143,11 +143,16 @@ abstract class BaseExpandedCandidateWindow<T : BaseExpandedCandidateWindow<T>> :
fcitx.launchOnReady { it.select(holder.idx) }
}
holder.itemView.setOnLongClickListener {
horizontalCandidate.showCandidateActionMenu(holder.idx, holder.text, holder.ui)
horizontalCandidate.showCandidateActionMenu(holder)
true
}
}
fun recycleCandidateViewHolder(holder: CandidateViewHolder) {
holder.itemView.setOnClickListener(null)
holder.itemView.setOnLongClickListener(null)
}
override fun onDetached() {
bar.expandButtonStateMachine.push(
ExpandedCandidatesDetached,

View File

@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* SPDX-FileCopyrightText: Copyright 2021-2024 Fcitx5 for Android Contributors
* SPDX-FileCopyrightText: Copyright 2021-2025 Fcitx5 for Android Contributors
*/
package org.fcitx.fcitx5.android.input.candidates.expanded.window
@ -40,6 +40,11 @@ class FlexboxExpandedCandidateWindow :
super.onBindViewHolder(holder, position)
bindCandidateUiViewHolder(holder)
}
override fun onViewRecycled(holder: CandidateViewHolder) {
recycleCandidateViewHolder(holder)
super.onViewRecycled(holder)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* SPDX-FileCopyrightText: Copyright 2021-2024 Fcitx5 for Android Contributors
* SPDX-FileCopyrightText: Copyright 2021-2025 Fcitx5 for Android Contributors
*/
package org.fcitx.fcitx5.android.input.candidates.expanded.window
@ -35,6 +35,11 @@ class GridExpandedCandidateWindow :
super.onBindViewHolder(holder, position)
bindCandidateUiViewHolder(holder)
}
override fun onViewRecycled(holder: CandidateViewHolder) {
recycleCandidateViewHolder(holder)
super.onViewRecycled(holder)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* SPDX-FileCopyrightText: Copyright 2024 Fcitx5 for Android Contributors
* SPDX-FileCopyrightText: Copyright 2025 Fcitx5 for Android Contributors
*/
package org.fcitx.fcitx5.android.input.candidates.floating
@ -94,6 +94,13 @@ class PagedCandidatesUi(
}
}
}
override fun onViewRecycled(holder: UiHolder) {
if (holder is UiHolder.Candidate) {
holder.ui.root.setOnClickListener(null)
}
super.onViewRecycled(holder)
}
}
private val candidatesLayoutManager = FlexboxLayoutManager(ctx).apply {

View File

@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* SPDX-FileCopyrightText: Copyright 2021-2024 Fcitx5 for Android Contributors
* SPDX-FileCopyrightText: Copyright 2021-2025 Fcitx5 for Android Contributors
*/
package org.fcitx.fcitx5.android.input.candidates.horizontal
@ -29,7 +29,6 @@ import org.fcitx.fcitx5.android.input.bar.ExpandButtonStateMachine.BooleanKey.Ex
import org.fcitx.fcitx5.android.input.bar.ExpandButtonStateMachine.TransitionEvent.ExpandedCandidatesUpdated
import org.fcitx.fcitx5.android.input.bar.KawaiiBarComponent
import org.fcitx.fcitx5.android.input.broadcast.InputBroadcastReceiver
import org.fcitx.fcitx5.android.input.candidates.CandidateItemUi
import org.fcitx.fcitx5.android.input.candidates.CandidateViewHolder
import org.fcitx.fcitx5.android.input.candidates.expanded.decoration.FlexboxVerticalDecoration
import org.fcitx.fcitx5.android.input.candidates.horizontal.HorizontalCandidateMode.AlwaysFillWidth
@ -106,10 +105,16 @@ class HorizontalCandidateComponent :
fcitx.launchOnReady { it.select(holder.idx) }
}
holder.itemView.setOnLongClickListener {
showCandidateActionMenu(holder.idx, candidates[position], holder.ui)
showCandidateActionMenu(holder)
true
}
}
override fun onViewRecycled(holder: CandidateViewHolder) {
holder.itemView.setOnClickListener(null)
holder.itemView.setOnLongClickListener(null)
super.onViewRecycled(holder)
}
}
}
@ -206,14 +211,17 @@ class HorizontalCandidateComponent :
private var candidateActionMenu: PopupMenu? = null
fun showCandidateActionMenu(idx: Int, text: String, ui: CandidateItemUi) {
fun showCandidateActionMenu(holder: CandidateViewHolder) {
val idx = holder.idx
val text = holder.text
val view = holder.ui.root
candidateActionMenu?.dismiss()
candidateActionMenu = null
service.lifecycleScope.launch {
val actions = fcitx.runOnReady { getCandidateActions(idx) }
if (actions.isEmpty()) return@launch
InputFeedbacks.hapticFeedback(ui.root, longPress = true)
candidateActionMenu = PopupMenu(context, ui.root).apply {
InputFeedbacks.hapticFeedback(view, longPress = true)
candidateActionMenu = PopupMenu(context, view).apply {
menu.add(buildSpannedString {
bold {
color(context.styledColor(android.R.attr.colorAccent)) {