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.
Related
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.
I was testing my android app on device by enabling device show layout boundaries in developer option on device.
I check my listview with inflated view with textviews , rating bar and other views clearly seen as shown below .
later I tried twitter app but surprise to see only single view ???
anyone know how to get twitter like single view on listview ??
anyone know how to get twitter like single view on listview ??
Each list item is a single custom View object, not a ViewGroup or layout. Essentially, all the content is drawn directly onto the Canvas in onDraw() rather than relying on child ImageView and TextView elements. Images can be drawn easily enough by calling Drawable.draw() or Canvas.drawBitmap() and text is typically drawing using a Layout.
Additionally, this means all touch events are handled directly inside onTouchEvent() to handle taps on the lower icons and/or the avatar image, so there are no click listeners.
Edit: Here's a quick 30 second example that should be enough to get you started: https://gist.github.com/devunwired/8704007
They are probably using the include tag to include another layout file
you can do the same thing if you make your list_row_item layout something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
>
<include layout="#layout/another_layout"/>
</LinearLayout>
The benefit to doing this is that you can swap layouts on the fly, perhaps even using a server side changes, rather than having to issue a software update
I have an app that uses this RibbonMenu and I wanted to know if it was possible to use the menu items to change the ContentView of the Activity instead of another activity to reduce the size of my app. I've tried doing this already,and it changed the content view perfectly, but i was not able to press the home button. I'm in a bit of a rush here, but i'll try to post code if anyone asks for it. thank you!
Menu items is UI element. It does nothing by itself. It however can trigger some more actions in your code. As for changing activity layout, yes, you can call setContentView() at any time you want.
to reduce the size of my app
this is not the way optimalizations should be done
I'm currently making an android app in which I'd like the user to be able to change the background image.
I've got 3 images and a screen where I can choose a picture and a button for applying.
The issue:
I can allow the user to see all images in the way I want, but I don't know how to set the selected image as app background.
What I want to do:
I want the user to click a button, which exports the selected image to "bakgrund.png" in "/res/drawable-mdpi" and replaces the current one. This would allow me to easily integrate the background switcher. Renaming of current files also works.
PS: My current background images are located in /res/drawable-mdpi named 1.png 2.png and 3.png.
Easiest way would be to call the setBackgroundResource(image_id) method on the root layout. Like if you have a LinearLayout which has android:id="#+linear" as the root layout in the layout xml, then this code will help:-
LinearLayout linearLayout=(LinearLayout) findViewById(R.id.linear);
linear.setBackgroundResource(R.drawable.1);//call this in the OnClickListener's OnClick Method
Firstly, you need different themes which has different backgrounds. So you may use this.setTheme method in your Activity.
Indeed I suggest you, two different layout (with different backgrounds but have same components) and using setContentView during onClick.
I hope it solves your issue.
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".