I have an Activity that has multiple fragments. The fragments all reference the data object in their MasterActivty. The MasterActivtiy may refresh its data.
How do I notify the fragments of data change?
I have tried Broadcasters and other methods, but I'm failing to understand how to do it.
I have looked at these SO questions One , two . but they didn't really make sense for my implementation. I am using a FragmentPagerAdapter
to load the different tabs.
Here is my code:
MasterActivity.java
public class MasterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_details));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_notes));
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new TabPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
refreshData();
}
public void refreshData() {
//do a background task to get data
//WHEN FINISHED TELL FRAGMENTS TO reloadData()
}
}
TabPagerAdapter.java
public class TabPagerAdapter extends FragmentPagerAdapter {
int tabCount;
public TabPagerAdapter(FragmentManager fm, int numberOfTabs) {
super(fm);
this.tabCount = numberOfTabs;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DetailsFragment tab1 = new DetailsFragment();
return tab1;
case 1:
NotesFragment tab4 = new NotesFragment();
return tab1;
default:
return null;
}
}
@Override
public int getCount() {
return tabCount;
}
}
A fragment
public class DetailsFragment extends Fragment {
private String TAG = getClass().getSimpleName();
public DetailsFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_details, container, false);
viewStatus = (LinearLayout) view.findViewById(R.id.viewStatus);
scrollViewDetails = (LinearLayout) view.findViewById(R.id.scrollViewDetails);
return view;
}
private void reloadData() {
Log.i(TAG, "REALOAD DETAILS FRAGMENT");
//Fill the text views with the data from the MasterActivity
}
}
The way I usually do this is:
Define an interface
public interface DataReloadListener { void onDataReloaded(Object data); // use your data type here }
Give the activity the ability to register/unregister the impls (fragments)
Add a data structure to your activity to keep track of listeners:
private List<DataReloadListener> mListeners;
Don't forget to initialize in the constructor:
mListeners = new ArrayList<>();
Add the register/unregister methods to the activity:
public synchronized void registerDataReloadListener(DataReloadListener listener) { mListeners.add(listener); } public synchronized void unregisterDataReloadListener(DataReloadListener listener) { mListeners.remove(listener); }
Have the fragment implement the interface and register/unregister for events
@Override public void onDataReloaded(Object data) { // update any fragment state here // if you are updating the UI, check that the fragment currently has a view if (getView() != null) { // update UI here } }
Override onAttach()
and onDetach()
in the fragments to register/unregister:
@Override public void onAttach(Activity activity) { super.onAttach(activity); ((MasterActivity) activity).registerDataReloadListener(this); } @Override public void onDetach() { ((MasterActivity) getActivity()).unregisterDataReloadListener(this); super.onDetach(); }
When the event occurs, call onDataReloaded
for all the registered listeners in the activity
public synchronized void onDataReloaded(Object data) { for (DataReloadListener listener : mListeners) { listener.onDataReloaded(data); } }
All this infrastructure is necessary because your fragment may or may not exist at the time of the event, depending on how the user swipes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.