Is it possible to refresh the view of a Fragment
Asked Answered
S

4

22

I changed the locale of my application programmatically, like following:

Resources res = context.getResources();

 DisplayMetrics dm = res.getDisplayMetrics();
 android.content.res.Configuration conf = res.getConfiguration();
 conf.locale = new Locale("cn");
 res.updateConfiguration(conf, dm);

After this, I would like to refresh my currently displayed fragment's view to display with new locale settings.

So, I firstly get the current fragment (that's the latest one in backstack):

BackStackEntry latestEntry=fragMgr.getBackStackEntryAt(fragMgr.getBackStackEntryCount()-1);
String str=latestEntry.getName();
Fragment fragment=fragMgr.findFragmentByTag(str);

After I get the currently showing fragment, I would like to refresh its view, but how to do it? Is it possible in Android to refresh the view of a fragment

Steelman answered 27/3, 2012 at 12:2 Comment(2)
do you mean invalidate the view?Paisley
@blackbelt, No, I mean refresh, just like how it works on a webpage, if you select a language from a webpage, the page get refreshed.Steelman
E
35

You can simply detach and attach fragment as below

    Fragment currentFragment = getFragmentManager().findFragmentByTag("FRAGMENT");
    FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
    fragTransaction.detach(currentFragment);
    fragTransaction.attach(currentFragment);
    fragTransaction.commit();

This will refresh the view and locale will change

Epidemic answered 8/5, 2013 at 12:14 Comment(13)
But how can i send some data to fragment? I am getting a blank view on the top now.Enosis
How are you sending data to fragment? You should use fragment.setArguments(Bundle extras); method to pass data. and when you refresh fragment the data will persist so you won't have any problem.Epidemic
yes i do this but Fragment life cycle is not being called for MyFragment Class.Enosis
This seems to work only for fragments that are attached to the activity programatically. For fragments that have been instanciated by the XML layout file of the activity only onActivityCreated is called when the activity is resumed and therefore the fragment shows still the old localization.Siddon
A quick note to help avoid problems for future users: In the google group here: groups.google.com/forum/#!topic/android-platform/QlkLMsncDwg Dianne Hackborn states that detaching a Fragment in a FragmentTransaction will not call onAttach() or onDetach() for that Fragment. Thus, don't rely on these lifecycle methods for refreshing your view(s).Saltigrade
If you're using the Support Library, instead of getFragmentManager(), use getFragmentManager().Overby
In my case, when I had only one Fragment in the back stack, it refreshed fine. When I had more than one, onDetach wasn't called, so I had to call detach/attach twice to make it work. Sounds ugly but that's how it happened.Favianus
How to know which is current fragment?Sublimate
Does that go in the Activity or Fragment? Also, how do I find the tag?Khelat
It goes under activity and you can only get fragment by tag if you have dynamically added and passed the tag (which is a simple string) however you can also get current fragment by id. More info about that #8532962Epidemic
Also, fragments added to a LinearLayout will move to the bottom when de- and attached like this.Invalidism
and you can tag like this fragmentTransaction.replace(android.R.id.content, fragment2,"tagfragment2");Oatis
Detaching and re-attaching a fragment in a single transaction is not guaranteed to work, the system may decide to optimize and just do nothing with the fragment. See my answer for a better approach.Houseclean
A
2

You could create a listener, which will be called when the locale changes. This will then remove the Fragment, and re add the Fragment. Your new locale should then be picked up.

Amman answered 27/3, 2012 at 12:10 Comment(2)
Where should the listener be created? can you please be more specific on how to do it?Steelman
Create your own interface, which your activity implements. Then register the listener with your fragment in onAttach(). When you change the locale, call the method in the interface, and remove/re-add the fragmentAmman
H
1

The solution that finally worked for me was this, in Kotlin:

        val manager = requireActivity().supportFragmentManager
        
        manager.beginTransaction().let {
            it.detach(this)
            it.commit()
        }
        manager.executePendingTransactions()
        manager.beginTransaction().let {
            it.attach(this)
            it.commit()
        }

Notice how I'm detaching and re-attaching the fragment in separate transactions. From the Android docs:

As a FragmentTransaction is treated as a single atomic set of operations, calls to both detach and attach on the same fragment instance in the same transaction effectively cancel each other out, thus avoiding the destruction and immediate recreation of the fragment's UI. Use separate transactions, separated by executePendingOperations() if using commit(), if you want to detach and then immediately re-attach a fragment.

Houseclean answered 26/7, 2021 at 17:47 Comment(0)
W
0

I finally found the solution to it! Just run your view update code in the UI thread

Example -

 getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                user_arrayList.add(name);
                adapter.notifyDataSetChanged();
                tv_total_users.setText("Total Users : "+user_arrayList.size());
            }
        });

Finally found this solution after trying for almost 4-5 hours!

Whipping answered 15/9, 2018 at 19:38 Comment(1)
Even if the question is 2 years old... IMHO this is the worst you can do. You should really use onCreate and onResume.Maximin

© 2022 - 2024 — McMap. All rights reserved.