Skip to content

Commit 39f6b07

Browse files
lukstbitmikehardy
authored andcommitted
Add utility method for setting a fragment result listener in a FragmentActivity
Introduces an utility method similar with the one which is available already available(platform code) for fragments: Fragment.setFragmentResultListener(). Example, current code: supportFragmentManager.setFragmentResultListener(REQUEST_REPOSITION_NEW_CARDS, this) { _, bundle -> repositionCardsNoValidation( position = bundle.getInt(RepositionCardFragment.ARG_POSITION), step = bundle.getInt(RepositionCardFragment.ARG_STEP), shuffle = bundle.getBoolean(RepositionCardFragment.ARG_RANDOM), shift = bundle.getBoolean(RepositionCardFragment.ARG_SHIFT), ) } vs. new code: setFragmentResultListener(REQUEST_REPOSITION_NEW_CARDS) { _, bundle -> repositionCardsNoValidation( position = getInt(RepositionCardFragment.ARG_POSITION), step = getInt(RepositionCardFragment.ARG_STEP), shuffle = getBoolean(RepositionCardFragment.ARG_RANDOM), shift = getBoolean(RepositionCardFragment.ARG_SHIFT), ) }
1 parent 6e6c4d1 commit 39f6b07

File tree

9 files changed

+66
-33
lines changed

9 files changed

+66
-33
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import com.ichi2.anki.snackbar.showSnackbar
110110
import com.ichi2.anki.ui.internationalization.toSentenceCase
111111
import com.ichi2.anki.utils.ext.getCurrentDialogFragment
112112
import com.ichi2.anki.utils.ext.ifNotZero
113+
import com.ichi2.anki.utils.ext.setFragmentResultListener
113114
import com.ichi2.anki.utils.ext.showDialogFragment
114115
import com.ichi2.anki.widgets.DeckDropDownAdapter.SubtitleListener
115116
import com.ichi2.annotations.NeedsTest
@@ -451,7 +452,7 @@ open class CardBrowser :
451452

452453
setupFlows()
453454
registerOnForgetHandler { viewModel.queryAllSelectedCardIds() }
454-
supportFragmentManager.setFragmentResultListener(REQUEST_REPOSITION_NEW_CARDS, this) { _, bundle ->
455+
setFragmentResultListener(REQUEST_REPOSITION_NEW_CARDS) { _, bundle ->
455456
repositionCardsNoValidation(
456457
position = bundle.getInt(RepositionCardFragment.ARG_POSITION),
457458
step = bundle.getInt(RepositionCardFragment.ARG_STEP),

AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ import com.ichi2.anki.dialogs.SyncErrorDialog.Companion.newInstance
136136
import com.ichi2.anki.dialogs.SyncErrorDialog.SyncErrorDialogListener
137137
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog
138138
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
139+
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction.Companion.REQUEST_KEY
139140
import com.ichi2.anki.export.ActivityExportingDelegate
140141
import com.ichi2.anki.export.ExportDialogFragment
141142
import com.ichi2.anki.export.ExportDialogsFactory
@@ -158,6 +159,7 @@ import com.ichi2.anki.snackbar.BaseSnackbarBuilderProvider
158159
import com.ichi2.anki.snackbar.SnackbarBuilder
159160
import com.ichi2.anki.snackbar.showSnackbar
160161
import com.ichi2.anki.utils.ext.dismissAllDialogFragments
162+
import com.ichi2.anki.utils.ext.setFragmentResultListener
161163
import com.ichi2.anki.utils.ext.showDialogFragment
162164
import com.ichi2.anki.widgets.DeckAdapter
163165
import com.ichi2.anki.worker.SyncMediaWorker
@@ -603,7 +605,7 @@ open class DeckPicker :
603605

604606
checkWebviewVersion(this)
605607

606-
supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
608+
setFragmentResultListener(REQUEST_KEY) { _, bundle ->
607609
when (CustomStudyAction.fromBundle(bundle)) {
608610
CustomStudyAction.CUSTOM_STUDY_SESSION -> {
609611
Timber.d("Custom study created")
@@ -620,16 +622,12 @@ open class DeckPicker :
620622
}
621623
}
622624

623-
supportFragmentManager.setFragmentResultListener(DeckPickerContextMenu.REQUEST_KEY_CONTEXT_MENU, this) { requestKey, arguments ->
624-
when (requestKey) {
625-
DeckPickerContextMenu.REQUEST_KEY_CONTEXT_MENU ->
626-
handleContextMenuSelection(
627-
arguments.getSerializableCompat<DeckPickerContextMenuOption>(DeckPickerContextMenu.CONTEXT_MENU_DECK_OPTION)
628-
?: error("Unable to retrieve selected context menu option"),
629-
arguments.getLong(DeckPickerContextMenu.CONTEXT_MENU_DECK_ID, -1),
630-
)
631-
else -> error("Unexpected fragment result key! Did you forget to update DeckPicker?")
632-
}
625+
setFragmentResultListener(DeckPickerContextMenu.REQUEST_KEY_CONTEXT_MENU) { _, bundle ->
626+
handleContextMenuSelection(
627+
bundle.getSerializableCompat<DeckPickerContextMenuOption>(DeckPickerContextMenu.CONTEXT_MENU_DECK_OPTION)
628+
?: error("Unable to retrieve selected context menu option"),
629+
bundle.getLong(DeckPickerContextMenu.CONTEXT_MENU_DECK_ID, -1),
630+
)
633631
}
634632

635633
pullToSyncWrapper.configureView(

AnkiDroid/src/main/java/com/ichi2/anki/IntroductionActivity.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ import android.os.Bundle
2323
import androidx.activity.result.ActivityResult
2424
import androidx.activity.result.contract.ActivityResultContracts
2525
import androidx.core.content.edit
26+
import androidx.core.os.BundleCompat
2627
import com.ichi2.anki.introduction.SetupCollectionFragment
2728
import com.ichi2.anki.introduction.SetupCollectionFragment.CollectionSetupOption
28-
import com.ichi2.anki.introduction.SetupCollectionFragment.Companion.handleCollectionSetupOption
29+
import com.ichi2.anki.introduction.SetupCollectionFragment.Companion.FRAGMENT_KEY
30+
import com.ichi2.anki.introduction.SetupCollectionFragment.Companion.RESULT_KEY
2931
import com.ichi2.anki.preferences.sharedPrefs
32+
import com.ichi2.anki.utils.ext.setFragmentResultListener
3033
import com.ichi2.annotations.NeedsTest
3134
import timber.log.Timber
3235

@@ -58,7 +61,9 @@ class IntroductionActivity : AnkiActivity() {
5861
super.onCreate(savedInstanceState)
5962
setContentView(R.layout.introduction_activity)
6063

61-
handleCollectionSetupOption { option ->
64+
setFragmentResultListener(FRAGMENT_KEY) { _, bundle ->
65+
val option =
66+
BundleCompat.getParcelable(bundle, RESULT_KEY, CollectionSetupOption::class.java) ?: error("Missing introduction option!")
6267
when (option) {
6368
CollectionSetupOption.DeckPickerWithNewCollection -> startDeckPicker()
6469
CollectionSetupOption.SyncFromExistingAccount -> openLoginDialog()

AnkiDroid/src/main/java/com/ichi2/anki/SingleFragmentActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.fragment.app.commit
2525
import com.ichi2.anki.android.input.ShortcutGroup
2626
import com.ichi2.anki.android.input.ShortcutGroupProvider
2727
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
28+
import com.ichi2.anki.utils.ext.setFragmentResultListener
2829
import com.ichi2.themes.setTransparentStatusBar
2930
import com.ichi2.utils.FragmentFactoryUtils
3031
import timber.log.Timber
@@ -74,7 +75,7 @@ open class SingleFragmentActivity : AnkiActivity() {
7475
replace(R.id.fragment_container, fragment, FRAGMENT_TAG)
7576
}
7677

77-
supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
78+
setFragmentResultListener(CustomStudyAction.REQUEST_KEY) { _, bundle ->
7879
when (CustomStudyAction.fromBundle(bundle)) {
7980
CustomStudyAction.CUSTOM_STUDY_SESSION,
8081
CustomStudyAction.EXTEND_STUDY_LIMITS,

AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsActivity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import anki.collection.OpChanges
2626
import com.ichi2.anki.CollectionManager.withCol
2727
import com.ichi2.anki.StudyOptionsFragment.StudyOptionsListener
2828
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
29+
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction.Companion.REQUEST_KEY
30+
import com.ichi2.anki.utils.ext.setFragmentResultListener
2931
import com.ichi2.libanki.ChangeManager
3032
import com.ichi2.ui.RtlCompliantActionProvider
3133
import com.ichi2.widget.WidgetStatus
@@ -49,7 +51,7 @@ class StudyOptionsActivity :
4951
}
5052
setResult(RESULT_OK)
5153

52-
supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
54+
setFragmentResultListener(REQUEST_KEY) { _, bundle ->
5355
when (CustomStudyAction.fromBundle(bundle)) {
5456
CustomStudyAction.CUSTOM_STUDY_SESSION,
5557
CustomStudyAction.EXTEND_STUDY_LIMITS,

AnkiDroid/src/main/java/com/ichi2/anki/browser/FindAndReplaceDialogFragment.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import com.ichi2.anki.browser.FindAndReplaceDialogFragment.Companion.ARG_SEARCH
4848
import com.ichi2.anki.browser.FindAndReplaceDialogFragment.Companion.REQUEST_FIND_AND_REPLACE
4949
import com.ichi2.anki.notetype.ManageNotetypes
5050
import com.ichi2.anki.ui.internationalization.toSentenceCase
51+
import com.ichi2.anki.utils.ext.setFragmentResultListener
5152
import com.ichi2.anki.utils.openUrl
5253
import com.ichi2.utils.customView
5354
import com.ichi2.utils.negativeButton
@@ -203,16 +204,15 @@ class FindAndReplaceDialogFragment : AnalyticsDialogFragment() {
203204
}
204205

205206
fun CardBrowser.registerFindReplaceHandler(action: (FindReplaceResult) -> Unit) {
206-
supportFragmentManager.setFragmentResultListener(REQUEST_FIND_AND_REPLACE, this) { _, bundle ->
207+
setFragmentResultListener(REQUEST_FIND_AND_REPLACE) { _, bundle ->
207208
action(
208209
FindReplaceResult(
209210
search = bundle.getString(ARG_SEARCH) ?: error("Missing required argument: search"),
210-
replacement =
211-
bundle.getString(ARG_REPLACEMENT) ?: error("Missing required argument: replacement"),
211+
replacement = bundle.getString(ARG_REPLACEMENT) ?: error("Missing required argument: replacement"),
212212
field = bundle.getString(ARG_FIELD) ?: error("Missing required argument: field"),
213-
bundle.getBoolean(ARG_ONLY_SELECTED_NOTES, true),
214-
bundle.getBoolean(ARG_MATCH_CASE, false),
215-
bundle.getBoolean(ARG_REGEX, false),
213+
onlyOnSelectedNotes = bundle.getBoolean(ARG_ONLY_SELECTED_NOTES, true),
214+
matchCase = bundle.getBoolean(ARG_MATCH_CASE, false),
215+
regex = bundle.getBoolean(ARG_REGEX, false),
216216
),
217217
)
218218
}

AnkiDroid/src/main/java/com/ichi2/anki/introduction/SetupCollectionFragment.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ import android.os.Bundle
3737
import android.os.Parcelable
3838
import android.view.View
3939
import android.widget.Button
40-
import androidx.core.os.BundleCompat
4140
import androidx.core.os.bundleOf
4241
import androidx.fragment.app.Fragment
43-
import androidx.fragment.app.FragmentActivity
4442
import androidx.fragment.app.setFragmentResult
4543
import com.ichi2.anki.R
4644
import com.ichi2.anki.introduction.SetupCollectionFragment.CollectionSetupOption.DeckPickerWithNewCollection
@@ -90,13 +88,5 @@ class SetupCollectionFragment : Fragment(R.layout.introduction_layout) {
9088
companion object {
9189
const val FRAGMENT_KEY = "collectionSetup"
9290
const val RESULT_KEY = "result"
93-
94-
/** Handles a result from a [SetupCollectionFragment] */
95-
fun FragmentActivity.handleCollectionSetupOption(handleResult: (CollectionSetupOption) -> Unit) {
96-
supportFragmentManager.setFragmentResultListener(FRAGMENT_KEY, this) { _, b ->
97-
val item = BundleCompat.getParcelable(b, RESULT_KEY, CollectionSetupOption::class.java)!!
98-
handleResult(item)
99-
}
100-
}
10191
}
10292
}

AnkiDroid/src/main/java/com/ichi2/anki/scheduling/ForgetCardsDialog.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.ichi2.anki.R
3131
import com.ichi2.anki.launchCatchingTask
3232
import com.ichi2.anki.preferences.sharedPrefs
3333
import com.ichi2.anki.snackbar.showSnackbar
34+
import com.ichi2.anki.utils.ext.setFragmentResultListener
3435
import com.ichi2.anki.utils.openUrl
3536
import com.ichi2.anki.withProgress
3637
import com.ichi2.annotations.NeedsTest
@@ -156,7 +157,7 @@ class ForgetCardsDialog : DialogFragment() {
156157
* @param cardsIdsProducer lambda which returns the list of cards for which to reset the progress
157158
*/
158159
internal fun AnkiActivity.registerOnForgetHandler(cardsIdsProducer: suspend () -> List<CardId>) {
159-
supportFragmentManager.setFragmentResultListener(ForgetCardsDialog.REQUEST_KEY_FORGET, this) { _, bundle: Bundle ->
160+
setFragmentResultListener(ForgetCardsDialog.REQUEST_KEY_FORGET) { _, bundle ->
160161
forgetCards(
161162
cardsIdsProducer = cardsIdsProducer,
162163
restoreOriginalPositionIfPossible = bundle.getBoolean(ForgetCardsDialog.ARG_RESTORE_ORIGINAL),
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/****************************************************************************************
2+
* Copyright (c) 2025 lukstbit <52494258+lukstbit@users.noreply.github.com> *
3+
* *
4+
* This program is free software; you can redistribute it and/or modify it under *
5+
* the terms of the GNU General Public License as published by the Free Software *
6+
* Foundation; either version 3 of the License, or (at your option) any later *
7+
* version. *
8+
* *
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
12+
* *
13+
* You should have received a copy of the GNU General Public License along with *
14+
* this program. If not, see <http://www.gnu.org/licenses/>. *
15+
****************************************************************************************/
16+
package com.ichi2.anki.utils.ext
17+
18+
import android.os.Bundle
19+
import androidx.fragment.app.Fragment
20+
import androidx.fragment.app.FragmentActivity
21+
import androidx.fragment.app.setFragmentResultListener
22+
23+
/**
24+
* Utility method that simplifies setting a fragment result listener in a [FragmentActivity].
25+
* Similar to [Fragment.setFragmentResultListener] library method.
26+
*
27+
* @param requestKey identifier for the request
28+
* @param listener a callback triggered when the result associated to [requestKey] is set.
29+
*/
30+
fun FragmentActivity.setFragmentResultListener(
31+
requestKey: String,
32+
listener: ((requestKey: String, bundle: Bundle) -> Unit),
33+
) {
34+
supportFragmentManager.setFragmentResultListener(requestKey, this, listener)
35+
}

0 commit comments

Comments
 (0)