how to override the recreation of fragments on screen flip - android

I have an activity that starts a fragment IF A CERTAIN BUTTON IS PRESSED (not in onCreate()).
currently, after the fragment is started, if the screen is rotated, the fragment is automatically recreated.
Side question: Does this behavior sound normal? In the other posts I've seen relating to this, people seem to have to put in code to recreate the fragment.
I want override this functionality and manually re-create the fragment my self. Is there a way to do this?

This is normal, although its a pain in the neck. You can override it by putting a configChange in your mainfest. In that case, onConfigChanged in your Activity will be called when your device is rotated. However if you're changing between different layouts for landscape and portrait you will then have to do that by hand.

Related

Android: After orientation change breaks connection between fragments

Application has two fragments: the first one contains a small representation of pager with photos, and the second one contains full screen pager. The second fragment replaces the first and passes a page number to the previous every time it changes. I made connection between my fragments just like Android Developers says.
Everything works till device orientation doesn't change. The first fragment is not recreated until it is not on top of stack, that is why all page number changes after that are missed for first fragment.
I do not really what to disable views destroy on orientation change, but looks like it is the only way.
What is the best solution?
In your manifest file in your parent activity in which fragments are write following line :
android:configChanges="keyboardHidden|screenSize|orientation"
Let me know if that works for you. Best of luck :)
When you change the orientation, the activity gets rebuild, thus essentially destroying the fragment that was built before the change in orientation.
Perhaps you would wish to refer to this https://developer.android.com/guide/topics/resources/runtime-changes.html on retaining the state during a change in configuration.

How to change orientation to Landscape in a fragment, but read from sensor when back to activity?

I start a fragment from activity, and this is when I want the orientation to change to landascape, but as soon as the app is back to the activity, I want the orientation to be dependent on the sensor. So far, I do it this way in my fragment:
getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
But when I go back to the activity, the screen is still in landscape, but instead, when I'm back to the activity, I want the the screen orientation to be dependent on the sensor.
What you are actually doing in the fragment is setting the orientation of the Activity containing it. getActivity().... So what you need to do is reset the orientation of the activity once the fragment is detached from the activity. You can, for example, override the onDetach() for your fragment and call the:
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
there. Or you could try to override the various methods within your fragment and see which works best for you.
The Best way is to use this code where you are going back to the activity. Because it will shift orientation to what user had set to its device.
yourActivityReference.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
if you donot want to use this then you can use
yourActivityReference.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

Android onConfigurationChanged() only in certain cases

I have stumbled on a problem, that, when the screen turns off while being in LANDSCAPE orientation, certain devices "rotate" the app back to PORTRAIT position (because the lockscreen is PORTRAIT only or something like that). I did a little research before posting this, and most popular work-around is to modify app's configuration change process to prevent activity being recreated after the configuration has changed.
But disabling activity recreation is not a solution for me, because my app supports both orientations with sepparate layout's etc.
So i would like to find out, is it possible to disable the configuration change only in special cases (Screen turned off and orientation is landscape)? Or is the right way to override onConfigurationChanged() then manually manage activity recreation inside that function (i guess simply setting different layout resources when orientation is changed simply wont cut it)?
Or is the right way to override onConfigurationChanged() then manually manage activity recreation inside that function?
Yes to an extent.
You cannot set the configChanges attribute programmatically. I guess it's to do with the way an Activity is created. They're created from the XML first and then the overridden methods in your activity implementation are invoked. There's nothing in the API that lets you change the configChanges attribute.
Now in your case it doesn't sound like you need to. If you support both orientations, then if the user locks the device and it rotates back why does it matter? From a UX perspective we know it's in portrait mode again. So should your app when it opens back up.

Stay on last tab on orientation change but not on app start

In the main activity of my app, I have three tabs which, when clicked, switch the contentView of the activity to a different layout. My problem is that when the orientation changes, the first tab is automatically selected and loads the first layout.
My first thought on how to fix this would be to just save the tab location in the savedInstanceState or a sharedPrefs file, but the problem with one of these solutions is that they will also happen when the app is first opened and OnCreate() is called.
To be clear, I want the following to happen:
On App load (fresh activity, onCreate() called)- Load first tab
always
On App resume (after app paused, Onresume() called)-Load last opened tab
On orientation change(after change, OnCreate() called?)- Load last opened tab
Basically I am trying to find a way to distinguish between an orientation change (witch calls OnDestroy() and onCreate()) and the onCreate() and onDestory() when the app is first launched.
If its possible, I'd rather not but the configChanges="orientation" line in my manifest, and handle the switch myself, because I've heard that can cause problems when dealing with different screen sizes and densities, etc.
Is there any way to accomplish this, or do I have to settle for a different behavior?
onSaveInstanceState is the right way to go. It will not persist after the activity has been finished, only when it's "going to a background state" or doing an orientation change.

Changing android:configChanges dynamically

I am creating a magazine app which uses a ViewPager and scrolls over different WebViews.
Most of the pages are portrait but some of them can be seen as landscape.
To handle this, I am using two methods in the Activity holding the ViewPager:
public void allowOrientationChanges() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
public void enforcePortrait() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
With this we make sure that all the pages that just need to be portrait stay portrait (calling getActivity().enforcePortrait()) and the ones that have portrait/landscape views goes through the whole restart process (calling getActivity().allowOrientationChanges()).
We reached a point where we want to add video to some of the magazine's pages. Unfortunately the HTML5 video tag isn't working fine so we added a VideoView to our layout.
The feature to add now is:
in portrait: Showing the video in a certain place. (Done!)
in landscape: Making the video full screen (like the youtube app).
I have been trying to do this and the only way I found is changing the size of the VideoView in the onConfigurationChanged() method in the Activity and notifying the fragment that the configuration changed. The problem with this is adding android:configChanges="orientation|keyboardHidden" to the Activity will "disallow" the views to be recreated.
The two possible solutions I thought of:
Changing the android:configChanges from the code and depending on the page but I couldn't find if that call exists.
Forcing a recreate on the onConfigurationChanged() method. I don't know how to force a recreation of the fragment.
Any ideas?
Maybe there is a way around it by defining the activity twice in the manifest with similar names and setting the second incarnation to enabled=false. Then switch the 2 activities around dynamically by calling PackageManager.setComponentEnabledSetting(....) it is just an idea though, not sure it if will work.
I am creating a magazine app which uses a ViewPager and scrolls over different WebViews.
Is this reliable?
Most of the pages are portrait but some of them can be seen as landscape.
Please allow all pages to be viewed in landscape. If your users want to view your app in landscape -- for example, they do not feel like turning their television on its side just to use your app -- please let them.
Any ideas?
In onResume() of the activity, have it notify the magazine page fragment to fix up its VideoView size/position based on the then-current Configuration (getResources().getConfiguration()).
I just fixed it. Thanks for your answers.
My solution was to make the Activity have the android:configChanges="orientation|keyboardHidden" flag.
After doing that I override the onConfigurationChanged() method inside the Fragment where I resize the WebView or the VideoView depending on what I need.
EDIT:
I just did a blog post about this.

Categories

Resources