Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable display orientation change when certain fragments are visible and disable when others

I use fragments in my app. Most of the fragments should have only one orientation - portait. So I forced holder activity to always be at portrait mode.

But one of my fragments should have both portrait and landscape modes. How to enable orientation change for only one fragment? Or I need to make it a separate activity to handle orientation without depending on other fragments?

like image 422
TpoM6oH Avatar asked Feb 25 '13 14:02

TpoM6oH


People also ask

Which method is called when screen changes orientation?

So instead of destroying and recreating your Activity, Android will just rotate the screen and call one of the lifecycle methods: onConfigurationChanged. If you have a Fragment attached to this Activity, it will also receive a call to its onConfigurationChanged method.

How to save data on orientation change?

You can save any Object by Overriding public Object onRetainNonConfigurationInstance () and calling getLastNonConfigurationInstance() in your onCreate method. but if you do this, you have to change your manifest and code, so the normal process for a configuartion change is used.


2 Answers

You will have to do it manually.

1) add this line to your activity tag android:configChanges="orientation|screenSize"

2) Override config change callback in you fragmtn or activity

@Override
public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig); 

   if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }

//Your fragment animation layout changing code

}
like image 129
Artem Zelinskiy Avatar answered Sep 20 '22 19:09

Artem Zelinskiy


I know this is old, but I'll add my two cents, in case it helps someone, as it's still a current issue.

Note: This answer was edited one day later I posted it, as I detected a problem with APIs lower than 26. After extensive testing, the following is my final answer. This solution works (tested) in API 21 and higher.

My case may not be identical to the posted question, so I'll specify what I have, and how I solved it.

  1. One Activity with multiple fragments.
  2. Only one fragment needs to be able to be both in portrait and landscape orientation, as it has the corresponding different layout versions. The rest must stay in portrait orientation and also the screen must not rotate while the app is in the foreground.
  3. I used Kotlin. For Java should be almost the same.

In every fragment that you have, you need to override onResume(). In it, you specify what orientation you want to "force".

In my case, I wanted only one fragment to be shown in portrait and landscape orientation, so I set requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED (this is the default value if it is not set), but as we will change the requestedOrientation in the rest of the fragments we must set it here too:

    override fun onResume() {

    super.onResume()

    activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

    //The rest of your code (if you have something else here).

    }

In the rest of the fragments I wanted to "force" portrait orientation, so I used the following:

    override fun onResume() {

    super.onResume()

    activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

    //The rest of your code (if you have something else here).

    }

That's all you need to make it work! The following is optional, but may be useful, as it was for me.

Optional 1:

If you have many fragments and you don't want to modify/add onResume() in each of them, you can create a subclass (PortraitFragment, for example) of Fragment() where you just override onResume(). Then you can derive from it all the fragments that you want to have this functionality.

open class PortraitFragment : Fragment() {

    override fun onResume() {
        super.onResume()

        activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    }

}

Optional 2:

Depending on your layout, you may also want to add this.
I use it as my layouts are not prepared for multi-window mode.

In the manifest add android:resizeableActivity="false":

    <activity android:name=".MainActivity"
    android:launchMode="singleTask"
    android:windowSoftInputMode="stateHidden|adjustPan"
    android:resizeableActivity="false">
like image 29
MatJB Avatar answered Sep 20 '22 19:09

MatJB