Sur Android, le transfert de données entre fragments peut être effectué de différentes manières: transfert via l'activité parent à l'aide du ViewModel ou même de l'API Fragments. L'API Fragment Target a récemment reçu le statut Obsolète et Google recommande d'utiliser plutôt l' API Fragment result .
Qu'est-ce que l'API Fragment result? Il s'agit d'un nouvel outil de Google qui vous permet de transférer des données entre des fragments à l'aide d'une clé. Pour cela, le FragmentManager est utilisé, qui à son tour implémente l'interface FragmentResultOwner. FragmentResultOwner agit comme un référentiel central pour les données que nous transmettons entre les fragments.
Comment ça fonctionne?
Comme mentionné ci-dessus, notre FragmentManager implémente l'interface FragmentResultOwner, qu'il stocke ConcurrentHashMap<String, Bundle>
. Ce HashMap stocke nos Bundles par clé de chaîne. Dès qu'un des fragments est signé (ou déjà signé), il reçoit le résultat pour la même clé.
Ce qu'il est important de savoir :
- -
setResultFragmentListener()
,setFragmentResult()
, - “Key + Result (Bundle)“ 1
-
STARTED
-
DESTROYED
ResultListener
?
:
FragmentManager.setFragmentResult(key: String, bundle: Bundle)
, Bundle. Bundle .
Kotlin
button.setOnClickListener {
val result = "result"
// Kotlin fragment-ktx
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
Java
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle result = new Bundle();
result.putString("bundleKey", "result");
getParentFragmentManager().setFragmentResult("requestKey", result);
}
});
FragmentManager FragmentResultListener . FragmentManager.setFragmentResult()
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Kotlin
setFragmentResultListener("requestKey") { key, bundle ->
// , Bundle-
val result = bundle.getString("bundleKey")
}
}
Java
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getParentFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
String result = bundle.getString("bundleKey");
}
});
}
2 : key: String bundle: Bundle.
— , . — Bundle, .
Parent Fragment Manger
FragmentManager- :
- FragmentManager ( Activity), FragmentManager, Activity
- , childFragmentManager ( )
, FragmentResultListener FragmentManager-.
/ FragmentResultListener, FragmentScenario API, .
, FragmentManager? , FragmentResultListener :
@Test
fun testFragmentResult() {
val scenario = launchFragmentInContainer<ResultFragment>()
lateinit var actualResult: String?
scenario.onFragment { fragment ->
fragment.parentFragmentManagager.setResultListener("requestKey") { key, bundle ->
actualResult = bundle.getString("bundleKey")
}
}
onView(withId(R.id.result_button)).perform(click())
assertThat(actualResult).isEqualTo("result")
}
class ResultFragment : Fragment(R.layout.fragment_result) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById(R.id.result_button).setOnClickListener {
val result = "result"
setResult("requestKey", bundleOf("bundleKey" to result))
}
}
}
, FragmentManager. FragmentResultListener .
@Test
fun testFragmentResultListener() {
val scenario = launchFragmentInContainer<ResultListenerFragment>()
scenario.onFragment { fragment ->
val expectedResult = "result"
fragment.parentFragmentManagager.setResult("requestKey", bundleOf("bundleKey" to expectedResult))
assertThat(fragment.result).isEqualTo(expectedResult)
}
}
class ResultListenerFragment : Fragment() {
var result : String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResultListener("requestKey") { key, bundle ->
result = bundle.getString("bundleKey")
}
}
}
FragmentResultListener , Google. , , , . , , , , .
Afin de pouvoir utiliser FragmentResultListener, nous devons inclure la version des fragments 1.3.0-alpha04 ou plus récente dans les dépendances :
- Version Java: androidx.fragment: fragment: 1.3.0-alpha04
- Version Kotlin: androidx.fragment: fragment-ktx: 1.3.0-alpha04
- Tests: androidx.fragment: test de fragments: 1.3.0-alpha04