Reputation: 334
I have FragmentA and FragmentB. I am trying to update the values of FragmentA from FragmentB
I have an interface:
interface FragmentCallback {
fun onDataSent(sendUpdatedData: String, position: Int?)
}
In FragmentA, I override the interface function. I also instantiate FragmentB and call setFragmentCallback function
class FragmentA: Fragment(), FragmentCallback {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
FragmentB().setFragmentCallback(this)
}
//This function is not being called from FragmentB...
override fun onDataSent(sendUpdatedData: String, position: Int?) {
updateRecyclerView(sendUpdatedData, position!!)
}
In FragmentB (which is on top of FragmentA) I instantiate the FragmentCallback interface. When I am done editing and pop the fragment(backstack), I call the overridden function from FragmentA(onDataSent).
class FragmentB: Fragment(){
private var fragmentCallback: FragmentCallback? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btn_save.setOnClickListener{
fragmentCallback?.onDataSent(et_new_text.text.toString(), position )
fragmentManager?.popBackStack()
}
}
fun setFragmentCallback(callback: FragmentCallback?) {
fragmentCallback = callback
}
}
For some reason, when I pop FragmentB and call onDataSent
, through the line:
fragmentCallback?.onDataSent(et_new_text.text.toString(), position)
onDataSent will actually NOT be called.
Upvotes: 0
Views: 1208
Reputation: 1242
Use a FragmentResultListener
in FragmentA
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setFragmentResultListener("requestKey") { key, bundle ->
val sendUpdatedData = bundle.getString("sendUpdatedData")
// Do something with the result...
}
}
Then in FragmentB
set the result:
btn_save.setOnClickListener{
val result = et_new_text.text.toString()
setFragmentResult("requestKey", bundleOf("sendUpdatedData" to result))
...
}
Have a look at the official documentation.
The old-fashioned way uses the Activity
to communicate between two fragments. You could also use a shared ViewModel to share data.
Upvotes: 2
Reputation: 791
You can try this too.
Let your activity implements your interface.
class YourActivity : FragmentCallback{
override fun onDataSent(sendUpdatedData: String, position: Int?) {
// Get Fragment A
val fraga: FragmentA? =
supportFragmentManager.findFragmentById(R.id.fragment_a) as FragmentA?
fraga.updateRecyclerView(sendUpdatedData,position)
}
}
In your fragmentB, send the data like this.
class FragmentB : Fragment() {
var mCallback: FragmentCallback? = null
override fun onAttach(activity: Activity) {
super.onAttach(activity)
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
mCallback = try {
activity as FragmentCallback
} catch (e: ClassCastException) {
throw ClassCastException(
activity.toString()
+ " must implement TextClicked"
)
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mCallback.onDataSent(et_new_text.text.toString(), position)
fragmentManager?.popBackStack()
}
override fun onDetach() {
mCallback = null // => avoid leaking, thanks @Deepscorn
super.onDetach()
}
}
In your FragmentA.
class FragmentA : Fragment() {
fun updateRecyclerView(sendUpdatedData: String, position: Int?) {
// Here you'll have it
}
}
Upvotes: 0