[android] Refresh Fragment at reload

In an android application I'm loading data from a Db into a TableView inside a Fragment. But when I reload the Fragment it displays the previous data. Can I repopulate the Fragment with current data instead of previous data?

This question is related to android android-fragments

The answer is


// Reload current fragment
Fragment frag = new Order();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_home, frag).commit();

For example with TabLayout: just implement OnTabSelectedListener. To reload the page, you may use implement SwipeRefreshLayout.OnRefreshListener i.e. public class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

the onRefresh() method will be @Override from the interface i.e.:

@Override
public void onRefresh() {
 loadData();
}

Here's the layout:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryLighter"
    app:tabGravity="fill"
    app:tabIndicatorColor="@color/white"
    app:tabMode="fixed"
    app:tabSelectedTextColor="@color/colorTextPrimary"
    app:tabTextColor="@color/colorTextDisable" />

Code in your activity

TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayout); tabLayout.setupWithViewPager(viewPager);

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (tab.getPosition() == 0) {
                yourFragment1.onRefresh();
            } else if (tab.getPosition() == 1) {
                yourFragment2.onRefresh();
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

To refresh the fragment accepted answer will not work on Nougat and above version. To make it work on all os you can do following.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        fragmentManager.beginTransaction().detach(this).commitNow();
        fragmentManager.beginTransaction().attach(this).commitNow();
    } else {
        fragmentManager.beginTransaction().detach(this).attach(this).commit();
    }

you can refresh your fragment when it is visible to user, just add this code into your Fragment this will refresh your fragment when it is visible.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // Refresh your fragment here          
  getFragmentManager().beginTransaction().detach(this).attach(this).commit();
        Log.i("IsRefresh", "Yes");
    }
}

Make use of onResume method... both on the fragment activity and the activity holding the fragment.


   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

this will only work if u use FragmentManager to initialize the fragment. If u have it as a <fragment ... /> in XML, it won't call the onCreateView again. Wasted my 30 minutes to figure this out.


This will refresh current fragment :

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();

You cannot reload the fragment while it is attached to an Activity, where you get "Fragment Already Added" exception.

So the fragment has to be first detached from its activity and then attached. All can be done using the fluent api in one line:

getFragmentManager().beginTransaction().detach(this).attach(this).commit();

Update: This is to incorporate the changes made to API 26 and above:

FragmentTransaction transaction = mActivity.getFragmentManager()
                        .beginTransaction();
                if (Build.VERSION.SDK_INT >= 26) {
                    transaction.setReorderingAllowed(false);
                }
                transaction.detach(this).attach
                        (this).commit();

For more description of the update please see https://stackoverflow.com/a/51327440/4514796


getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();

GeneralInfo it's my Fragment class GeneralInfo.java

I put it as a method in the fragment class:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}

I had the same issue but none of the above worked for mine. either there was a backstack problem (after loading when user pressed back it would to go the same fragment again) or it didnt call the onCreaetView

finally i did this:

public void transactFragment(Fragment fragment, boolean reload) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    if (reload) {
        getSupportFragmentManager().popBackStack();
    }
    transaction.replace(R.id.main_activity_frame_layout, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

good point is you dont need the tag or id of the fragment either. if you want to reload


Use a ContentProvider and load you data using a 'CursorLoader'. With this architecture your data will be automatically reloaded on database changes. Use third-party frameworks for your ContentProvider - you don't really want to implement it by yourself...


Easiest way

make a public static method containing viewpager.setAdapter

make adapter and viewpager static

public static void refreshFragments(){
        viewPager.setAdapter(adapter);
    }

call anywhere, any activity, any fragment.

MainActivity.refreshFragments();

In case you do not have the fragment tag, the following code works well for me.

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof "NAME OF YOUR FRAGMENT CLASS") {
 FragmentTransaction fragTransaction =   (getActivity()).getFragmentManager().beginTransaction();
 fragTransaction.detach(currentFragment);
 fragTransaction.attach(currentFragment);
 fragTransaction.commit();}
}

Here what i did and it worked for me i use firebase and when user is logIn i wanted to refresh current Fragment first you will need to requer context from activity because fragment dont have a way to get context unless you set it from Activity or context here is the code i used and worked in kotlin language i think you could use the same in java class

   override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
    val context = requireActivity()
    if (auth.currentUser != null) {
        if (isVisibleToUser){
            context.supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
        }
    }

}

protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Do write viewpagerAdapter.notifyDataSetChanged(); in onResume() in MainActivity. Good Luck :)