简体   繁体   中英

Update tabpager fragments data on Activity update

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM