Cruces Cruces - 4 months ago 27
Android Question

How to change screen orientation, without creating a new activity on android?

I do not know if the title is correct, here is what happens.

I have an application which works differently on a phone and on a tablet, on a phone it shows as portrait on a tablet it shows as landscape.

To achieve this I created a class called CoreActivity which is extended by all my activities and does the following:

public class CoreActivity extends Activity {
protected boolean _landscape = false;

public boolean isPhone() {
int layoutSize = getScreenLayoutSize();
return (layoutSize == Configuration.SCREENLAYOUT_SIZE_SMALL || layoutSize == Configuration.SCREENLAYOUT_SIZE_NORMAL);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isPhone() && !_landscape) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}


protected int getScreenLayoutSize() {
return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK);
}
}


My problem occurs when I wish to show a screen on a phone setup on landscape mode, to do this I use the following:

@Override
protected void onCreate(Bundle savedInstanceState) {
_landscape = true
super.onCreate(savedInstanceState);
}


The problem is, that on a phone, if the user is holding the phone on portrait mode (as one would, since most of the application is in portrait mode) then the activity gets created and destroyed and then recreated. But if they are holding it on landscape mode, then it is only created once.

My problem occurs because on the onCreate method I launch the threads that load data, and I also show fragments.

Is there a way to avoid this problem? is there a way to launch an activity from the start on portrait mode and not change it, or have it not create twice?

Thanks in advance for any help you can provide

Answer

Recreating occurs just because you are forcing to, by calling setRequestedOrientation probably in order to set screen orientation. However you don't need to check and change it by code. You can do it via xml file. You can set different xml files depending on the screen size. But it is little bit hack so there is no guarantee in the future.

On the manifest file you can force by:

<activity
   android:name="com.my.example.MyActivity"
   android:screenOrientation="landscape"/>  // or portrait

So as far as I understand you want to force portrait for small sizes and landscape(or sensor) for larger screen sizes. But above configuration applies for all screen sizes. Here is the tricky part: landscape portrait sensor etc. are all integers defined here. As you might guess you can write android:screenOrientation=0 instead of landscape. What we know from beginning lessons of android, we can define integers in xml files then their values might vary on screen size. So..

You should first create different integers.xml files for different screen sizes. i.e.:

values
 - integers.xml
values-large
 - integers.xml

for values/integers.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="orientation">1</integer>  // 1 for portrait
</resources>

for values-large/integers.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="orientation">0</integer> // 0 for landscape
</resources>

and finally you you have to manipulate manifest file by:

<activity
   android:name="com.my.example.MyActivity"
   android:screenOrientation="@integer/orientation"/>  // read constant from xml files

You can also use sensor , fullSensor, nosensor, locked, behind, reverseLandscape, reversePortait options too. But I am warning you, this is a hack solution.