Fool-Proof Way to Handle Fragment on Orientation Change

Fool-proof way to handle Fragment on orientation change

You are creating a new fragment every time you turn the screen in your activity onCreate(); But you are also maintaining the old ones with super.onCreate(savedInstanceState);. So maybe set tag and find the fragment if it exists, or pass null bundle to super.

This took me a while to learn and it can really be a pain when you are working with stuff like viewpager.

I'd recommend you to read about fragments an extra time as this exact topic is covered.

Here is an example of how to handle fragments on a regular orientation change:

Activity:

public class MainActivity extends FragmentActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

if (savedInstanceState == null) {
TestFragment test = new TestFragment();
test.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, test, "your_fragment_tag").commit();
} else {
TestFragment test = (TestFragment) getSupportFragmentManager().findFragmentByTag("your_fragment_tag");
}
}
}

Fragment:

public class TestFragment extends Fragment {

public static final String KEY_ITEM = "unique_key";
public static final String KEY_INDEX = "index_key";
private String mTime;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);

if (savedInstanceState != null) {
// Restore last state
mTime = savedInstanceState.getString("time_key");
} else {
mTime = "" + Calendar.getInstance().getTimeInMillis();
}

TextView title = (TextView) view.findViewById(R.id.fragment_test);
title.setText(mTime);

return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("time_key", mTime);
}
}

How can I handle Orientation change so Fragment doesn't load?

Do you use viewPager or just add fragment into your activity? One way is to save data that you want to maintain on rotation into onSaveInstanceState(Bundle outState) bundle and then restore that data inside onCreate using

 if(savedInstanceState != null) {
//get your data
}

or simply add your fragment only when the activity was loaded (not reloaded after device rotation)

if(savedInstanceState == null) 
{
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

YourFragment fragment = new YourFragment();

fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}

Anyways you should definitely check this and this questons, they might be helpful.

Put code in Activity or Fragment to handle orientation change?

You put the code where the views are... It's really that simple.

res/layout-land should keep the exact same view IDs.

For example, MainActivity would load both res/layout/activity_main.xml and res/layout-land/activity_main.xml automatically for you depending on orientation.

findViewById will work appropriately if you don't change any ID values

There is a whole documentation page on this. Notice they use retained Fragments, but that is not necessary.

Also Android Studio: Creating landscape layouts

Android Fragment lifecycle over orientation changes

You're layering your Fragments one on top of the other.

When a config change occurs the old Fragment adds itself to the new Activity when it's recreated. This is a massive pain in the rear most of the time.

You can stop errors occurring by using the same Fragment rather than recreating a new one. Simply add this code:

if (savedInstanceState == null) {
// only create fragment if activity is started for the first time
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

FragmentOne fragment = new FragmentOne();

fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else {
// do nothing - fragment is recreated automatically
}

Be warned though: problems will occur if you try and access Activity Views from inside the Fragment as the lifecycles will subtly change. (Getting Views from a parent Activity from a Fragment isn't easy).

How to handle orientation change in fragment in viewpager programmatically?

As always in such situations, it seems that the decision should be difficult to implement. In fact, it was three lines:

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ViewGroup viewGroup = (ViewGroup) getView();
viewGroup.removeAllViewsInLayout();
View view = onCreateView(getActivity().getLayoutInflater(), viewGroup, null); viewGroup.addView(view);
}

Here where I found it

Redrawing the fragment is not the best idea if it keeps some data (plays video, map, etc.) because I have no dynamically changing data there, and I had to show the same thing, only in a different orientation, I used this approach if you need to change the orientation and did not lose the data you must read this.



Related Topics



Leave a reply



Submit