Escucha de resultados de fragmentos de Android





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?



imagen

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



imagen


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



All Articles