Refresh Fragment at reload
Asked Answered
E

22

138

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?

Effy answered 20/12, 2013 at 11:11 Comment(4)
show us some code please. Where do you load your data, where do you start your fragment, where do you store your values?Hex
This should solve your porly described problem: #6503689Limbate
please provide more info-code snippetFlak
Try to use Swipe-to-Refresh To Your App see this https://mcmap.net/q/168364/-fragment-refresh/…Kahl
H
225

I think you want to refresh the fragment contents upon db update

If so, detach the fragment and reattach it

// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();

Your_Fragment_TAG is the name you gave your fragment when you created it

This code is for support library.

If you're not supporting older devices, just use getFragmentManager instead of getSupportFragmentManager

[EDIT]

This method requires the Fragment to have a tag.
In case you don't have it, then @Hammer's method is what you need.

Handball answered 20/12, 2013 at 11:14 Comment(20)
This gives following error - java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=3, data=null} to activity {xont.virtusel.v4.controller/xont.virtusel.v4.controller.sale.InvocieBrandActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceStateEffy
I call this @ onActivityResult.Effy
Well, does it make sense to call it in onActivityResult? It seems that your intent is null (you see: data=null). I do it like: I update my db and after I detach/reattach my fragment.Liturgist
Cannot find a place to use this. Everywhere it throws exception. Some advice, please? Thanks.Pseudo
Everywhere it throws exception... isn't this a bit vague? You could make a new question, including all the needed details, to have a chance to get a good answer.Liturgist
@Elizabeth make sure your Fragment has a tag properly setLiturgist
i used id like frg = getFragmentManager().findFragmentById(R.id.table_fragment_container);Rattler
Then, you used the @Hammer method.Liturgist
What if I want to do the same as above from Activity? Also, I never gave my Fragment a tag...Uboat
@Uboat What if I want to do the same as above from Activity? Yes, you're supposed to. I never gave my Fragment a tag Then Hammer's answer will do for you.Liturgist
@Rotwang Thanks for your reply I just took a shortcut rather than do the long code but that helped paved the way :)Uboat
This solution is not working any more in the new version of support-v4-library (25.1.0). Explanation here : #41271358Ornithischian
@RajeshNasit You can explicitly clear it by adding something like yourEditText.setText("");Liturgist
I know it but my case is #44581551Dignadignified
@RajeshNasit Manually reset your Views in the Fragment's onAttach() method.Liturgist
Warning: this trick works on Oreo only if you are using Support Fragments!Styracaceous
This answer is outdated. With the new navigation system, we can navigate to the same page : Navigation.findNavController(requireActivity(), R.id.fragment_container_view).navigate(R.id.selfFragment)Reparative
@Handball Thank you. This answer helped. However, for androidx.navigation:navigation-fragment-ktx version 2.5.3, Android Studio's lint suggests separating the detach() and attach() method calls onto different FragmentTransaction instances.Fernandafernande
@Fernandafernande Well, try the suggested methods by Android Studio. This answer of mine is 10 years old, and there are probably better ways to manage the situation, nowadays.Liturgist
It doesn't do anything. Fragment is still in place; nothing has changedEversole
C
161

This will refresh current fragment :

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Cham answered 10/8, 2015 at 15:1 Comment(14)
where to put this code? inside activity or fragment itself?Parra
You put it inside the fragment that needs to be refreshed.Cham
i apply your code, its working fine but my fragment keep refresing and hang also.. too much loading.. how to stop refreshment continuty.Stedman
@SagarChavada where did you put the code ? You have to put it in a one-time event like when data is refreshed.Cham
I put this code in onCreateView. it hanged my mobile and after one minute my mobile restarted. where to put this code ?Joann
user getSupportFragmentManager to support old android versionsSelimah
How do i call from activity?Uboat
This didn't work for me. I have a fragment inside a view pager. The edit text fields in the fragment still have the old text.Anecdote
This solution is not working any more in the new version of support-v4-library (25.1.0). Explanation here : #41271358Ornithischian
Recursion, recursion, endless callsRechabite
Using this creates within onResume in the fragment makes a loop, how to avoid it?Horodko
How to use this in onResume() to avoid recursion?Overmatch
Best place to use this code in OnActivityResult. It will call once. For me, it is working perfectly.Transonic
I can confirm that applying this workaround in the current fragment will cause an infinite loop of calls...Detaching and attaching the fragment should be done in side the hosting activityOverset
F
37

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();
    }
Farad answered 19/1, 2015 at 18:31 Comment(4)
what will be the fragment Id, I haven't declared fragment id anywhere. How and where to declare it?Parra
Can't seem to use getActivity() in my Activity. Should I use Activity.this...?Uboat
@NarendraJi it's FrameLayout id only that is where you place your fragments in container.Santanasantayana
Please remove that extra brace. It caused a lot of trouble for me.Defelice
G
26

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();
    }
Gourde answered 21/11, 2018 at 6:40 Comment(2)
Using two transactions works for me. Thank you for this idea.Sharynshashlik
After updating my gradle build files, fragments wouldn't reload anymore. Your answer solved the issue. Thanks.Cilia
M
12

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");
    }
}
Maloney answered 27/8, 2018 at 10:34 Comment(3)
so slow it takes 3 second till it reloadsSpacesuit
This seems to be working well with viewpager adapterTrapezius
setUserVisibleHint is deprecatedLamontlamontagne
T
9

If you are using NavController, try this (kotlin):

val navController = findNavController()
navController.run {
    popBackStack()
    navigate(R.id.yourFragment)
}
Trill answered 9/11, 2021 at 13:30 Comment(2)
And can you please explain why this should work?Barbarous
Sorry, forgot to complete the code.Trill
B
6

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://mcmap.net/q/168365/-refresh-fragment-is-not-working-any-more

Branchia answered 27/9, 2017 at 11:54 Comment(1)
Please provide your answer with clear descriptions. Don't write the code, give the explanation about the code which you have shared, so that others can also understand and it will be helpful. I request you to read the FAQ Section in-order to use Stack Overflow in an effective manner.Fanatical
S
6

In case you are using Navigation Components
You can use navigate(this_fragment_id) to navigate to this fragment but in a new instance. Also you have to pop the backstack before to remove the actual fragment.

Kotlin

val navController: NavController = 
     requireActivity().findNavController(R.id.navHostFragment)
navController.run {
            popBackStack()
            navigate(R.id.this_fragment_id)
        }

Java

NavController navController = 
    requireActivity().findNavController(R.id.navHostFragment);
navController.popBackStack();
navController.navigate(R.id.this_fragment_id);
Sandarac answered 3/7, 2021 at 16:20 Comment(0)
F
3
   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.

Footgear answered 14/4, 2017 at 3:12 Comment(0)
H
1

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()
        }
    }

}
Hamforrd answered 18/2, 2019 at 11:28 Comment(0)
D
1
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();
}
Drum answered 16/1, 2020 at 6:7 Comment(0)
D
0

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...

Dentition answered 15/10, 2016 at 9:13 Comment(0)
B
0

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

Baty answered 29/8, 2017 at 9:6 Comment(0)
P
0

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

Pongee answered 10/9, 2019 at 12:28 Comment(0)
C
0

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) {

        }
    });
Croft answered 12/8, 2020 at 16:52 Comment(0)
U
0
// Reload current fragment
Fragment frag = new Order();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_home, frag).commit();
Underage answered 20/9, 2020 at 20:35 Comment(2)
This question was answered nearly seven years ago, and has two answers with more than 100 votes each, alongside thirteen other answers. Several use a similar overall approach—though none use R.id.fragment_home specifically. What is the benefit to your approach? Why would someone want to use it over one of the highly-upvoted answers? It's fine to add new answers to old questions, but please edit your answer to provide a summary of why your answer contributes value to this thread.Edgington
I had tried the above two methods with 100+ votes too but none solved my issue, as the first one is using findFragmentByTag, but in my case that returns a null value, and for the second answer "ft.detach(this)" I wasn't able to use "this" as it always shows red line coz I was using location listener and instead of giving me a fragment this returns a location listener, so the only way I was able to reload my fragment was method in the answer.Underage
W
0

None of these answers worked for me so I might as well post my solution if anyone still has problems with this. This solution works only if you are using the Navigation component.

Go to your navigation graph and find the fragment you want to refresh. Create an action from that fragment to itself. Now you can call that action inside that fragment like so.

private void refreshFragment(){
    // This method refreshes the fragment
    NavHostFragment.findNavController(FirstFragment.this)
            .navigate(R.id.action_FirstFragment_self);
}
Woolard answered 15/11, 2021 at 10:16 Comment(2)
How do i get FirstFragment.this in self Fragment?Kuntz
@Freax FirstFragment is the fragment where I'm calling this method from. Change it to your fragment's name.Woolard
A
0
Below code reloads the current fragment onClick of button from Parent Activity.

        layoutNews.setOnClickListener(v -> {
             FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
             ft.replace(R.id.fragment_container, fragNews);
             ft.detach(fragNews);
             ft.attach(fragNews);
             ft.commit();
        });
Alagez answered 13/1, 2022 at 7:20 Comment(0)
V
0

If you are in a fragment then use:

findNavController().run {
    popBackStack()
    navigate(R.id.your_fragment)
}
Vladamir answered 19/12, 2022 at 17:11 Comment(0)
H
0
findNavController().run {
  popBackStack()
  navigate(R.id.nameFragment)
}

you can refresh it easily by using findNavController() in Kotlin

Heptarchy answered 27/7, 2023 at 17:51 Comment(1)
This answer already exists.Bitchy
A
-1

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();
Anabal answered 13/11, 2018 at 12:44 Comment(0)
J
-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

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

Jolenejolenta answered 28/12, 2017 at 7:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.