This question already has answers here:
How can I get the current screen orientation?
(9 answers)
Closed 3 years ago.
I searched everywhere in the site and found no answer. So far I managed to keep important states of my App when orientation changes but now I want to have separate fragments for each orientation:
If (Portrait Mode) => attach fragment portrait to activity
if (Landscape Mode) => attach fragment landscape to activity
I don't want just two separate layouts, but two different fragments (this is because I want to add some functionality that's "impossible" to achieve in portrait mode). How can I achieve this?
We suggest checking your orientation in onResume() method of your activity like bellow.
#Override
protected void onResume() {
super.onResume();
int mOrientation = this.getResources().getConfiguration().orientation;
if (mOrientation == Configuration.ORIENTATION_PORTRAIT) {
// code for portrait mode
//Add your Portarait fragment
} else {
// code for landscape mode
// Add your landscape fragment
}
}
You can check for orientation changes in onConfigurationChanged of the activity that you're attaching your fragments.
So, what you need to do is,
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//set the fragment for landscape mode
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
//Set the fragment for portrait mode
}
}
Also, don't forget to add
android:configChanges="orientation|screenSize" in the activity tag in your manifest file that you're handling configuration changes.
Related
I'm totally new to android and I got my first task which is supposed to be simple, so the task is that I should add a password toggle to the password input field so that it can be shown/hidden when pressed and that was easy I only added this line in the TextInputLayout and it worked:
app:passwordToggleEnabled="true"
Now the thing is when I rotate the phone I lose the state of the toggle, so if I'm showing the password and I rotated the phone by default it hides the text, I was reading about Bundle savedInstanceState but I can't reference the default password toggle from inside the java class
You should use savedInstanceState for the best practice. But you can also set configChanges to your activity. Your activity won't re-create again when rotate.
android:configChanges="orientation|screenLayout|screenSize|navigation"
You can also handle screen rotate event in your activity.
#Override
public void onConfigurationChanged(#NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int orientation = newConfig.orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// portrait
} else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// landscape
}
}
I'm allowing all possible orientation for my app both for portrait and landscape (small-normal-large-xlarge) but after testing it on a small screen, I just didn't like how it appears so, what I'm trying to do is disable landscape for small layouts. Is there a way to do this ?
All I found was changes to do on manifest file but I believe that by reconfiguring the manifest I will apply the changes to all layouts.
The easiest way is to put this in the onCreate() method of all your Activities (better yet, put it in a BaseActivity class and extend all your Activities from it)
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
if (isLargeDevice(getBaseContext())) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
} else {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
You can use this method to detect if the device is a phone or tablet:
private boolean isLargeDevice(Context context) {
int screenLayout = context.getResources().getConfiguration().screenLayout;
screenLayout &= Configuration.SCREENLAYOUT_SIZE_MASK;
switch (screenLayout) {
case Configuration.SCREENLAYOUT_SIZE_SMALL:
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
return false;
case Configuration.SCREENLAYOUT_SIZE_LARGE:
case Configuration.SCREENLAYOUT_SIZE_XLARGE:
return true;
default:
return false;
}
}
Check this link you can check the type of device and set orientation as needed
Android: allow portrait and landscape for tablets, but force portrait on phone?
You can programatically handle runtime configuration changes like that
in your manifest:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
in your activity
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
///check the screen size and change it to potrait
}
}
or check this answer to see how to check the screen size and change it
for example 480 screen size devices:Apply in oncreate method:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
if(width==480){
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
I've been looking for a way to have the blank detail side of my fragment layout host a welcome screen (or something - login perhaps) on start up. Afterwards, when a user presses one of the left side menu items, I'd like to eliminate the fragment for the remainder of the program run. I don't want to add it to the backstack, as that messes up my configuration changes. I've considered using shared prefs to host a boolean about whether the fragment has been displayed. The only concern with this method is where to safely reset the boolean value for the next run of the app. I'm of the impression that there's no gaurantee that the onStop, onDetach etc. will definitely get called upon closing of the app, so if the app got closed in the wrong state, it would be rendered useless ( the first fragment wouldn't display - crash )
Anyone have any ideas on how I could implement a filler for the right side of the app upon startup?
I've been trying to add something to the onCreate of my main activity thus far with no success.
Thanks in advance.
Ken
If your fragment can be part of its own Activity, you can use the android:noHistory="true" attribute to keep the Activity off of the backstack. If your user tries to navigate backwards, it'll hit the bottom of the backstack twice before exiting your application.
If you can't split your fragment into its own activity, noHistory may not work -- I can't say as I haven't tried it myself.
I was able to come up with a solution to creating a welcome or login screen which will display both fragments and activities from the main activity. Seems to be working fine as tested.
private boolean welcomeShown;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_list);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
((MainFragment) getSupportFragmentManager().findFragmentById(
R.id.item_list)).setActivateOnItemClick(true);
}
if (savedInstanceState != null){
welcomeShown = savedInstanceState.getBoolean("displayed");
}
if(!welcomeShown){
if (mTwoPane){
WelcomeFragment welcomeFragment = new WelcomeFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container, welcomeFragment)
.commit();
}
else{
Intent welcomeIntent = new Intent(this, WelcomeActivity.class);
startActivity(welcomeIntent);
welcomeShown = true;
}
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("displayed", true);
}
I have a ListActivity which I want to show when the phone's orientation is portrait and I have another normal Activity which I want to show when the user rotates the phone to landscape mode.
Some code:
public class ListActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this.getResources (). getConfiguration (). orientation == Configuration.ORIENTATION_PORTRAIT) {
//Do stuff
}else if (this.getResources (). getConfiguration (). orientation == Configuration.ORIENTATION_LANDSCAPE) {
Intent myIntent = new Intent(getApplicationContext(), AnotherActivity.class);
startActivity(myIntent);
}
}
}
This approach works, but has some problems. Is there a more correct way? The problem with this method is that when you rotate your phone and press the back button, the screen just becomes black since the phone is not rotated. So should I implement the rotation in another way, or modify the back button in some way so that the user cant return to the previous Activity?
It is a normal way. But it is long - 5 sec of waiting.
There is another way:
register orientation change as a configuration change
A.
activity android:name=".SomeActivity"
android:label="#string/app_name"
android:configChanges="orientation"
And process it as a config change.
B.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
SetupActivity();
}
How do you detect that the user has changed the orientation of the display screen from portrait to landscape and vice versa?
The Android application must adjust to the new orientation. The system should be sending a change of orientation message to all open applications so that they can adjust. I could not find anything about this in the docs? Sorry if i copy these statement from somewhere else but i'm kinna new ina android/java, can someone guide me along?
Its just one of the Preference screen in multiple tabs i have, but i just want mere change of screen orientation when the phone position changes...
public class Tab2Activity extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.tab2);
}
}
Android will automatically recreate (destroy and then create) your activity when the orientation changes. If you want a special layout for landscape, you can create a special resource file in the layout-land folder, which will be loaded after the activity is recreated.
On the other hand, if you want to override the default behavior so that you can do something custom when the orientation changes, you can override the onConfigurationChanged method like so:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
//do something if portrait...
}
}
http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged%28android.content.res.Configuration%29
EDIT: in code (add this to your Activity):
#Override
public void onConfigurationChanged(Configuration _newConfig){
super.onConfigurationChanged(_newConfig);
int height = getWindowManager().getDefaultDisplay().getHeight();
int width = getWindowManager().getDefaultDisplay().getWidth();
if(width > height){
// landscape
}else{
// portrait
}
}