Orientation changing padding on activity - java

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.

Related

Is there any way to make a layout inside a fragment fixed to portrait while in landscape mode?

I have a fragment in which, when in landscape mode need to show another layout, while in portrait another layout?
Is there any way to achieve this behaviour?
My requirement is my bottom menu should be locked in portrait even when the orientation changes.
As my center view has been rotated, others are not changed.
Is it possible in android, if yes, how to implement it?
In your res folder, create layout-land folder. Create an xml layout file with the same name as the layout you are currently using for your fragment. In the newly created layout file, define your landscape layout.

Placing layouts on top of each other - problem

I have a relative layout tree, let's say that I have a couple of buttons in root layout and other one is placed on top of the buttons, covering them with it's backgound.
Visually everything is ok, but I still can activate invsible buttons placed under the layout, is there any property related to this?
I have tried elevation, translationZ, etc. I would like to avoid programatically fixing the problem (isShown for example), is there anything else I can change in xml to prevent them from activating?
In your layout xml file, add setClickable="true" to the same layout you've set the background to.

android Change orientation removing button

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.

New Activity for different orientation Android

I know that I can create a folder called layout-land in my res/ folder and Android will handle this automatically. My problem is what if I want to call a new Activity when my orientation changes from portait to landscape?
What I have:
An xml file for portrait that consists of a button and a scrollview
An xml file for landscape that contains multiple buttons, textviews,
and edittexts
Both are called main.xml (but in their respective folders)
One Activity that calls setContentView(main.xml)
This activity however has to initialize all the buttons, textviews, etc, but when I change the orientation back to portrait, it force closes because those buttons are not in that xml file!
How can I get around this?
Try to use getResources().getConfiguration().orientation to check the current orienation.
So you can avoid inflating the wrong ressources when u tilt your device.
-> http://developer.android.com/reference/android/content/res/Configuration.html#orientation
Another (but bad!) approach could be to override onConfigurationChanged, so your land-layout won't be used and you can push another activity when tilting. Its like:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//push new activity via intent
}
But I wouldn't recommend this for you. Give the first approach a try and tell me wether this worked for you. ;)
Thomas's solution should work, but also know that if the buttons that are common to both portrait and landscape mode do the same thing, you could simply check if findViewByID(...) is null before trying to cast it/assign it. From the documentation of findViewByID(...) The view if found or null otherwise. Something like this should work:
Object x = findViewByID(R.id.something) != null;
if(x != null)
{
//cast it to whatever it really is (textview, button, etc)
//Add whatever listeners you want
}
Mind you, I would still go with Thomas's solution because then you only have to check one property, as opposed to having to check for null on each of the controls that differ between layouts.

Fragment without a view crashes on configuration change

I have an UI where I need a Fragment to be displayed (with a view) in landscape mode but not in portrait mode. In portrait mode it should still be available but will display its result using ListPopupWindow instead.
I figured I could handle this by using the <fragment /> tag for the landscape layout while creating the fragment programmatically if it wasn't started (in the case when we are in portrait).
This works fine as long as you start out in landscape, if you start in portrait where the fragment is created programmatically your application will crash when you rotate the emulator when it tries to attach the fragment to your layout:
java.lang.IllegalStateException:
Fragment did not create a view.
at
android.app.Activity.onCreateView(Activity.java:4095)
The docs for Fragment.isInLayout() seems to hint that it should be able to handle it this way:
Return true if the layout is included
as part of an activity view hierarchy
via the tag. This will
always be true when fragments are
created through the tag,
except in the case where an old
fragment is restored from a previous
state and it does not appear in the
layout of the current state.
So the question is how to do this correctly or if there is something I'm missing?
UPDATE:
Seems like isInLayout() isn't behaving as it should currently as well. It returns false if you have added a Fragment to a container manually.
Also, if you add a Fragment manually to a container and then rotate (the device) to a layout that does not contain that layout it will crash:
Caused by:
java.lang.IllegalArgumentException: No
view found for id 0x7f060011 for
fragment SearchFragment{4042f868 #2
id=0x7f060011 SearchFragment} at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:722)
Have you come up with an answer to this? I was having a similar problem, and managed to come up with a solution. You can easily do what you are attempting as follows:
Create two different layouts one in the layout directory, one in the layout-land directory. The one in the layout-land directory will be used in landscape mode. As a placeholder, where you want your fragment to go, use s FrameLayout element, and id it, say with the id "my_fragment". The layout in the layout directory should not contains any element with that id.
In your onCreate method, use findViewById(R.id.my_fragment) to locate the fragment placeholder. If it exists, you are in landscape mode and should add your fragment (if it does not exist already): add(R.id.my_fragment, new MyFragment, "myFragment). If you get null, you are in portrait mode and should not create the fragment.
Be very careful that you never replace a fragment created using a tag, with one that you create dynamically in your program. A fragment for which isInLayout returns true is a completely different beast, that one for which it returns false. Their lifecycles are entirely different. Replacing one with the other will lead to the dreaded IllegalStateException "Fragment did not create a view" problem.
-blake
Your problem can also be due to not having a lanscape layout for the fragment you are using. You might have one for the portrait and so your program runs fine but when you rotate your device, the OS probably looks for the view in the landscape folder and doesnt find the view so declares it as missing. Check that you have view both in the folder "layout" and "layout-land".

Categories

Resources