Android Fragment Result Listener





On Android, transferring data between fragments can be done in different ways: transferring through the parent Activity using the ViewModel or even the Fragments API. The Fragment Target API has recently received the Deprecated status and Google recommends using the Fragment result API instead .



What is Fragment result API? This is a new tool from Google that allows you to transfer data between fragments using a key. For this, the FragmentManager is used, which in turn implements the FragmentResultOwner interface. FragmentResultOwner acts as a central repository for the data we pass between fragments.



How it works?



image

As mentioned above, our FragmentManager implements the FragmentResultOwner interface, which it stores ConcurrentHashMap<String, Bundle>. This HashMap stores our Bundles by string key. As soon as one of the fragments is signed (or already signed), then it receives the result for the same key.



What is important to know :



  • - 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



image


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. , , , . , , , , .



In order to be able to use the FragmentResultListener, we need to connect the version of fragments 1.3.0-alpha04 or newer in the dependencies :



  • Java version: androidx.fragment: fragment: 1.3.0-alpha04
  • Kotlin version: androidx.fragment: fragment-ktx: 1.3.0-alpha04
  • Tests: androidx.fragment: fragment-testing: 1.3.0-alpha04



All Articles