New Activity for different orientation Android - java

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.

Related

check the current activity in if condition

I am working on an android application so I need to check if the user is at some activity say "xyz" then proceed or change background colour etc. How can I check the current activity in if condition like
if (xyz activity){
set Background Color
// Do something
}
How can I do this in runtime so that whenever user goes to any screen this condition becomes true and then the below code works?
Try this:
if(getActivity() instanceof TheWantedActivity){
//...
}
If i follow your question than put your background code in your OnResume(); if the activity is in foreground its onResume always called.
In each activity or "screen" a user can see or interact with, a class is designated to that view. So if you want to set the background to activity xyz, you do not need to check if the user is there. You need to just load the background you specify within the onCreate(Bundle bundle) method with "setContentView(R.layout.your_activity_layout)". This layout should be stored in your res/layout folder after you create an activity. So for example, if your activity is named StartActivity.java, the layout file saved in res/layout will most likely be named activity_start.xml.
If the answer Saurabh provided isn't promising enough you can take
ActivityLifecycleCallbacks in your Application class, It will only work API 14 and above

Is it possible to switch the layout to a different layout whilst an activity in running in Java?

Instead of moving views in a current layout, I was wondering if i could instead load a different layout whilst the program is running.
For example in the on create i would use:
setContentView(R.layout.layout1);
and then in an on click listener i would use:
setContentView(R.layout.layout2);
I say this since I am using a custom dialogue which prevents me from producing a dialog to overwrite it. I have attempted it but so far have only received errors. I would really like to know if this is possible.
This is possible, but risky and not recommended for a final product. The problem is, you cannot access already defined views once you have switched views. You need to assign them all again for the new layout. So once you switch the content view, re-initialize all of your views and anything that references the old layout. Calling a view from the old layout will cause a crash or error message.
Like CodeMagic said, it is best to use fragments and the FragmentManager for this. And really, this is not a stable way to produce good code. I recommend using separate fragments and using backstacks and such so that not only will your game work, but you can easily navigate back to the original fragment, rather than use makeshift code that may barely work.
After setContentView(R.id.yourLayout) is called, you need to re-instantiate all of your other views. So like say you used an ImageView view to show the color changes, well you need to instantiate that ImageView after you setContentView(R.id.yourLayout) so that it pulls from the new layout, and does not reference to the original layout.
Example:
ImageView imageView;
public void onCreate(Bundle b){
super.savedInstanceState(b);
setContentView(originalLayout);
//Instatiate all of your original Views.
imageView = (ImageView) R.id.yourImageView;
}
public void onButtonClick(View){
setContentView(newLayout);
imageView = (ImageView) R.id.yourNewImageView;
//All other views
}
If you need an example of the fragment manager solution go here: https://developer.android.com/training/basics/fragments/creating.html
and look through some of their examples on how to properly do what you are trying to do.

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.

Implementing Instagram like in-app navigation system on Android

I have to implement a navigation system similar to the one used in the Instagram Android client.
There should be a permanent tabbar on the bottom of the screen all the time.
When the user navigates deeper within one of these tabs, lets say to a detail view, then switches to another tab, and then switches back to the previous tab, the last shown (deeper) detail view should be shown, and on back presses, it should be iterating back till the main view of the said tab.
What I have came up with so far is the following:
I have a MainAcitvity showing the menu on the bottom.
On selecting a menu point, the appropriet Fragment is shown.
When the user navigates further within a Fragment, it then asks the MainActivity to change its content by the given criterias, resulting in changing the Fragment shown.
I add all the Fragment changes to the backStack, by calling the FragmentTransaction's addToBackStack() method.
I am stuck at this point, and cannot figure out how to switch fragments on back presses, and how to handle tab navigations when deeper views are shown instead the main views of the tabs.
I am thinking of using my own separate "backstack implementations" for every tab. When the user navigates deeper within a tab, i generate a unique "tag" and use that tag when calling addToBackStack() and also putting the tag in the "backStack" implemented by me. In case the user navigates again to this tab, i can check if i have any tags in the "backStack" for that tab, and if so, then look up that entry in the real backStack in the fragmentManager of the MainActivity, and switch to it.
I could not come up with anything better yet. Is there any better/simpler way to attchieve the said behaviour? Am i missing something? (I know this is really bad application design in the Android world, but it is another question)
I am posting an answer since the question is pretty dead, yet the conclusion might be helpful for others.
We ended up sticking with the old fashioned NavgationDrawer pattern, which worked well. But in the meantime I had to implement a library project which provided a Fragment to the hosting Application which had its own custom logic. This Fragment then used its ChildFragmentManager, to add another Fragments inside itself. ChildFragmentManager is ported back in the Android Support v4 lib, so you can use it basicly everywhere.
So lets say you want x Menu points in which you can navigate deeper. Those will be the Fragments using their own ChildFragmentManagers to add other Fragments to navigate deeper within that Menu. ChildFragmentManagers have their own back stack, so you dont have to worry that much about handling states. If another Menu is selected, you can look up the corresponting Fragment in the MainActivitys FragmentManager, and change back to it, or add it if it has not yet been added.
Be careful, you have to implement back functionality yourself, since ChildFragmentManagers will not get the backPressed event automatically. You can do this by handling the onBackPressed event in your MainActivity.
#Override
public void onBackPressed() {
boolean handled = false;
if(getFragmentManager().getBackStackEntryCount() == 0){
// No menu added
return super.onBackPressed();
}
Fragment frag = getFragmentManager().getBackStackEntryAt(getFragmentManager().getBackStackEntryCount() - 1);
if (frag instanceof XMenuFragment && frag.isVisible()) {
FragmentManager childFm = frag.getChildFragmentManager();
if (childFm.getBackStackEntryCount() > 0) {
// pop the last menu sub-Fragment
childFm.popBackStack();
handled = true
}
}
if(!handled){
super.onBackPressed();
}
}
I used a different code, so it might contain errors, but i hope that the point of the concept is clear.

Change Linear layout background image on activity startup

I change Linear Layout background image via this code:
mainlayout.setBackgroundResource(R.drawable.back);
But i want do this on every time that activity starts, In first start and switching between activities. I put this code inside an IF statement in onCreate() but background not change! Of course when i set this code to a button works fine! How and where i have to put my code?
my complete code is:
//check theme id
if(myDbHelper.gettheme()==1)
{
mainlayout.setBackgroundResource(R.drawable.back);
}else if(myDbHelper.gettheme()==2)
{
mainlayout.setBackgroundResource(R.drawable.blueback);
}
You need to put your code into the onResume() method.
Here are details that will explain why
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
You may want to refer to the Android activity lifecycle, but I'd recommend the onResume() method.
I'm assuming based off your code snippet you have the image you want as a background as a drawable resource already in project. If so you could just go into the XML and add into the linerayout:
android:background="#drawable/back"
This should just set the background within the XML layout avoiding having to have code set it within one of the activity life-cycle functions.
Though in the case you wanted different themes as I just saw in the original post (seemed to be edited since I was typing this up), you could try storing the constant int of the R.drawable that the user wants as the background or theme, and have your DB Helper's getTheme() return that reference to set the background without the if statements.
Such saying the user changes their preference to R.drawable.black or .blueback store the int within the DB so it get return by gettheme rather than a 1 or 2 enumeration. Not sure if this would be a best practice though.
EDIT: Are you sure theme is either 1 or 2?
If you want to do it everytime, why don't you just define it as mainLayout's background in your layout.xml? Otherwise, use onResume() rather than onCreate().

Categories

Resources