I've set android:configChanges="orientation|screenSize" on an activity to stop it restarting the activity everytime the orientation changes. Now this works fine but I think it's stopping the correct layouts from being used.
E.G. I have different layout folders for different orientations and sizes of screen. So if I start the activity in portrait, when I change the orientation to landscape, it's not using my landscape layout.
Also if I start the activity in landscape, when I change the orientation to portrait, it's not using my portrait layout.
Basically what I want the app to do is not start the activity again once the orientation changes, but use the correct layout when the orientation is changed!
I was thinking I could use the onConfigurationChanged method to explicitly change the layout in code?
Thanks for any input
when you use android:configChanges="orientation|screenSize" this tells to Android that you will maintain these changes by yourself - this means you have to change your layout (setContentView) and initialize it manually (set values of controls - EditTexts, Spinners etc.)
So What I've ended up doing is keeping android:configChanges="orientation|screenSize" in the manifest file. Doing it this way stops me being able to use my correct layout folders for portrait and landscape.
To overcome this issue, I override the onConfigurationChange method to set the correct information I needed for the activity to run as expected once the orientation changes. below is the code I've used:
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
setContentView(R.layout.hearing_test);
//Any other information needed for the activity to work correctly
}
Thanks for the help and guidance #mihail, helped me get to the bottom of the issue.
That is exactly why the Activity is destroyed and recreated: to apply new resources.
Do not use android:configChanges="orientation" if you have different layouts for portrait and landscape mode.
Related
I've one major issue. I built one chat app from scratch using Firebase, Java and Android, which contains many activities and class. Now suddenly I found that I forgot to set UI for Landscape mode (which is like default tablet mode). I opened my app and rotate to landscape, and UI looks very bad, even some part is not visible. I'm actually planning to publish on play store just for learning purpose. So is there any easy way to do this?
Should I restrict, so that user not able to rotate the screen for every activity like below is mation in either java or xml through?
In XML:
<activity android:name=".SomeActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
In Java:
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
I also don't know that how can I do this for all activity? Should I have to crate duplicate activities for all activity? and how can I do this? where can I attach? I really don't have any idea about this. Please help me.
Studio generates layout for you just adjust the generated layout as per need and that layout will be used automatically
Should I restrict, so that user not able to rotate the screen for
every activity like below is mation in either java or xml through?
You shouldn't restrict user to one orientation, If design specs of you layout is ideal for landscape then go for it
I also don't know that how can I do this for all activity? Should I
have to crate duplicate activities for all activity? and how can I do
this? where can I attach? I really don't have any idea about this.
Please help me.
With manifest solution, yes, you have to do this for every activity entry in manifest file.
either do it via manifest or via xml.
To set orientation of all activities, you can create a base activity and extend all activities from it where your base activity set the orientation. e.g
// no need to set orientation in manifest
class BaseActivity extends AppCompactActivity{
oncreate(...){
super.oncreate(..);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
class YourOtherActivities extends BaseActivity{
oncreate(...){
super.oncreate(..);
setContentView(..);
}
}
The first activity(locked portrait orientation) has 2 buttons that both open the second activity but A button opens it in portrait and B button opens it in landscape orientation.
The problem is that when B button opens the second activity (which is in dialog configuration and the first activity is shown in the background) the first activity changes orientation with the second one, thus restarting.
The question is, A) Can i prevent first activity from changing orientation and B) Can i disable orientation change animation so that the screen doesn't look like turning from portrait to landscape but just becoming landscape instead?
P.S For the A) question i know how to use saved state but i want to avoid it.
Use Below Code in Manifest:
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
Edited:
Sorry there is no way to control the rotation animation. This is done way outside of your app, deep in the window manager where it takes a screenshot of the current screen, resizes and rebuilds the UI behind it, and then runs a built-in animation to transition from the original screenshot to the new rebuilt UI. There is no way to modify this behavior when the screen rotation changes
My app allows orientation change, it also allows for app continuation when orientation is changed by changing the activity line in AndroidManifest to this:
<activity android:name="com.cynetstudios.frequencyselector.main" android:configChanges="orientation|screenSize">
Problem:
However, starting my app can be done in 2 states:
Vertical
Application acts normally, default padding, no issue. Vertical Start, Change to Horizontal
Horizontal
Application has large padding on sides, thus being carried over onto the Vertical layout. Horizontal Start, Change to Vertical
I have done some research:
It is mentioned to add the configChange="Orientation" which I have done, but also to add into my main class:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
this.recreate();
}
This does solve the problem but recreates the old issue of the application itself is recreated/relaunched, this any current tasks/threads is killed.
Any suggestions for this padding issue?
create the different layout.xml file for horizontal orientation and tablet
Create a separate directory named layout-land and create separate layout's for landscape and keep them inside layout-land directory.
If you want same padding on both the sides on both state of orientation then define some padding value to the parent layout. so it will keep the same padding on both the state.
As suggested by other users, creating a layout-land folder and copying over my activity layout xml file into this new layout-land folder helped solving my problem
The cause was due to a dp change in my dimens.xml. The horizontal xml defined the horizontal margin of 64pd while I defined it as 16dp.
Changing this to 16dp solved my issue,
also the onConfigurationChanged() was not necessary in my case.
When I click a button in my App, the screen orientation will automatically go to landscape :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
The screen get to landscape successfully but it caused my onConfigurationChanged not working anymore.
I tried to use: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); but it makes no difference.
What should I do, to make the screen go to landscape, when I click the button, without turning off the onConfigurationChanged?Or do you have any other ways to accomplish this?
If you are using API13 or higher as your target,
in your manifest you need to add ScreenSize to your configChanges:
android:configChanges="orientation|screenSize|keyboardHidden"
That should do the trick!
My layout sometimes does not position elements properly. I tried a lot of solutions but unique working one is rotate from portrait to landscape and then return from landscape to portrait. Then layout is automaticaly redrawed and fits perfectly. I set orientation|keyboard so content is not reloaded, only redrawed. How to redraw content programmaticaly like landscape-portrait does? Thank you.
EDIT: I tried following and has no effect
getWindow().getDecorView().findViewById(android.R.id.content).invalidate();
getWindow().getDecorView().findViewById(android.R.id.content).requestLayout();
Activity has set main layout on onCreate setContentView(R.layout.main);
Layout "main" contains a TabHost and Admob.
Layout "view" contains a webview ("id:myWebview") that is shown on tab1.
And also tried to invalidate them! webview, layout main and layout view and crashes
Did you try to invalidate() the root view?
findViewById(android.R.id.content).invalidate();
This should redraw the whole layout.
When screen orientation changes, Android recreates the current Activity.
Try calling measure(int, int) or requestLayout(). Otherwise there is no chance to programmatically relayout views.
Call requestLayout() only and read View class description for more informations.
If this is unsafe or bad practice please do correct me. I tried all these methods as well and out of desperation decided to just try calling my onCreate again and it worked. So for now I'll be using onCreate(null) to refresh my view when I update data. Again, please let me know if this is unsafe or a bad practice and if possible a working alternative.