En Android, la transferencia de datos entre fragmentos se puede hacer de diferentes maneras: transfiriendo a través de la Actividad principal usando ViewModel o incluso la API de Fragments. La API de Fragment Target ha recibido recientemente el estado Desaprobado y Google recomienda utilizar la API de resultados de Fragment en su lugar .
¿Qué es la API de resultados de fragmentos? Esta es una nueva herramienta de Google que le permite transferir datos entre fragmentos usando una clave. Para ello, se utiliza FragmentManager, que a su vez implementa la interfaz FragmentResultOwner. FragmentResultOwner actúa como un repositorio central de los datos que pasamos entre fragmentos.
¿Cómo funciona?
Como se mencionó anteriormente, nuestro FragmentManager implementa la interfaz FragmentResultOwner, que almacena ConcurrentHashMap<String, Bundle>
. Este HashMap almacena nuestros paquetes por clave de cadena. Tan pronto como uno de los fragmentos esté firmado (o ya esté firmado), recibe el resultado de la misma clave.
Qué es importante saber :
- -
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. , , , . , , , , .
Para poder usar FragmentResultListener, necesitamos incluir la versión de los fragmentos 1.3.0-alpha04 o más reciente en las dependencias :
- Versión de Java: androidx.fragment: fragment: 1.3.0-alpha04
- Versión de Kotlin: androidx.fragment: fragment-ktx: 1.3.0-alpha04
- Pruebas: androidx.fragment: fragment-testing: 1.3.0-alpha04