The fragment put to the mFragment in FragementStateAdapter.class is managed by the
void placeFragmentInViewHolder(@NonNull final FragmentViewHolder holder)
method, which is package private and we do not have access and in this method the fragment is added to the mFragment manager with tag "f" + holder.getItemId()
which is the same as "f" + position
.
scheduleViewAttach(fragment, container);
mFragmentManager.beginTransaction()
.add(fragment, "f" + holder.getItemId())
.setMaxLifecycle(fragment, STARTED)
.commitNow();
mFragmentMaxLifecycleEnforcer.updateFragmentMaxLifecycle(false);
For this reason, we can override the onBindViewHolder
method while a fragement shall be displayed.
@Override
public void onBindViewHolder(@NonNull FragmentViewHolder holder, int position, @NonNull List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (position == 0) {
String fragmentTag = "f" + holder.getItemId();
Log.v(TAG,"fragmentTag is : " + fragmentTag);
MyFragment fragment0 = (MyFragment) this.mFragmentManger.findFragmentByTag(fragmentTag);
if (fragment0 != null) {
Log.v(TAG,"onBindViewHolder updating fragment ...");
// do what ever you want to update the MyFragment
fragment0.update(payloads);
} else {
Log.v(TAG,"onBindViewHolder called, but fragment0 is null!");
}
}
}
In my case the this.mFragmentManager
is cashed through the constructor.
public MyFragmentStateAdapter(@NonNull Fragment fragment) {
super(fragment); // this calls the fragment.getChildFragmentManager().
this.mFragmentManger = fragment.getChildFragmentManager();
}
And the createFragment()
is:
@NonNull
@Override
public Fragment createFragment(int position) {
if(position == 0){
if (this.fragment0 == null) {
this.fragment0 = MyFragment.getInstance();
}
return this.fragment0;
} else {
Log.v(TAG, "position " + position + " is called");
return null;
}
}
Finally, call the update in somewhere else to trigger the update:
ViewPager2.getAdapter().notifyItemChanged(0, null);
// 0 is the fragment position of the fragment0 and null is payload.