Inconsistent layout_weight in simulator vs Android Studio renderer - android

Below see the XML code and a screenshot.
Summary:
One parent LinearLayout with weightSum = 100
One child LinearLayout with layout_weight = 25
One child LinearLayout with layout_weight = 75
Result:
In Android Studio layout renderer the children ratio is OK (25:75)
In the simulator the ratio between the children is not OK (clearly not 25:75)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="100">
<LinearLayout
android:background="#color/md_orange_600"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="25"
android:layout_gravity="center_horizontal">
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_margin="#dimen/default_separator"
android:background="#color/md_green_400"
android:layout_weight="75">
</LinearLayout>
</LinearLayout>
Some notes:
The layout_height is 0dp on both children (as it is recommended for weights)
I colored the background so the area assignment is visible

Found the root problem:
It turns out my main activiy layout has a CoordinatorLayout as a primary container.
CoordinatorLayout does children placement like FrameLayout, therefore my AppBarLayout and the main fragment container (FrameLayout) overlapped.
I just enclosed them both into a vertical oriented LinearLayout and now they don't overlap.
Corollary, my 2 cents for developers out there: It is tempting to bypass problems without understanding their real cause (I could have just add layout_marginTop on my fragment to "shift it down") but in the end, bypass after bypass you end up understanding less and less of your own application. Always look to understand the real cause of the problem you experience, then the solution will be real too.

Related

Android Studio layout management problems

I'm new to android studio... So I've been trying to make a simple app. When I want to put two linear layouts in another one, One of them goes out of the frame!
I don't know if I'm doing this right or not.
Also here are the pictures (the second one is the problem):
1)http://i.imgur.com/2H1hOxk.jpg
2)http://i.imgur.com/5IeZHsC.jpg
thanks
From your pictures, your parent linear layout which contains the other two linear layouts has its orientation set to "horizontal". It must be set to "vertical" to be above each other...
In your parent linear layout, you will find this:
android:orientation="horizontal"
Change it to:
android:orientation="vertical"
For horizontal orientation, you need to set both of the inner LinearLayout widths to 0dp and set their weights to 1.
For veritcal orientation, you need to set both of the inner LinearLayout heights to 0dp and set their weights to 1.
Without the weight attribute, since the first LinearLayout width is set to match_parent, it takes up the entire LinearLayout.
Example:
in your case of a horizontal layout:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="0d"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
<LinearLayout
android:layout_width="0d"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>

ScrollView doesn't work

My Layout has a few complex layouts and they are pretty big. That's why I need a ScrollView. But whatever I try it doesn't work.
Here is my layout file:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="fill_parent"
android:fillViewport="true"
android:layout_weight="1"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.33"
android:id="#+id/Linear1"
>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#color/tileColor1"
android:layout_weight="1"
android:id="#+id/tileLayout1"
android:onClick="openFirst"
>
I have only posted a part of it but all the closing tags are ok and inside my RelativeLayout there are 2 textViews and an image. There are 9 more RelativeLayouts with the same structure.
How can I fix the problem and why doesn't it work? It doesn't even show a scrollbar.
EDIT
I have uploaded my full layout to pastebin
EDIT 2
On the developer.android it is said:
You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
Mine doesn't deal with the scrolling at all. I suppose it is this way because I edit LayoutParams in code. How do I fix this?
1. Try removing android:layout_weight="1" and android:orientation="vertical".
2. Ensure that there is only one ViewGroup inside the ScrollView (i.e. one child as they say). I assume you've done this, but as you haven't provided your full layout I couldn't confirm it.
ScrollView only accepts one child view. So wrap everything inside it in a LinearLayout with wrap_content set as height and you're set.
I had the same problem, and I do not know if my solution helped (mainly because it is a very late response), but my ScrollView not worked since set up a layout that fit exactly on the screen, so it was not necessary to create scrolling. When increased my layout (I put all my items with
android:layout_height = WRAP_CONTENT) became operational.

Putting two child layout inside a parent layout with equal weight distribution in Android

I want to use two child layout (one linear layout and one relative layout) inside a parent layout (relative layout) in such a way that both of the child layout will take exactly half of the screen and items inside of each child layout will not cause one child layout to get more width than another one!
It is pretty easy, use parameter layout_weight in children of LinearLayout, something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent">
</RelativeLayout>
<RelativeLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent">
</RelativeLayout>
</LinearLayout>
If I understand correctly from your illustration, the red box is a RelativeLayout, whereas the green boxes are a LinearLayout and a RelativeLayout.
A simple solution would be to center an empty View inside the RelativeLayout and align the two child Views against it:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="#+id/v_center" />
<View
android:id="#+id/v_center"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerInParent="true" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/v_center" />
</RelativeLayout>
A nice little bonus here is that you can provide some spacing between the two by specifying the View's dimensions.
Beware, however, that RelativeLayouts aren't very efficient, and nesting them is an especially bad idea. I suggest using the hierarchy viewer tool to inspect the layout timings to make sure it's relatively fast, and to try to avoid nesting the layouts in this fashion.

Left aligning images in LinearLayout using gravity or linear_gravity in XML

First off, this is not a duplicate question, to best of my ability I've tried all (there are many) similar questions. Solutions to such problems appear to be very subjective, specific to a given scenario.
My layout currently appears as follows. Black boxes are images (logo and body, respectively), colours represent each layout:
My XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:padding="0px"
android:layout_margin="0px"
android:orientation="vertical">
<LinearLayout
android:layout_weight="16"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:gravity="top|center"
android:orientation="horizontal">
<ImageView
android:id="#+id/logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/logo"
android:layout_gravity="top|center" />
</LinearLayout>
<LinearLayout
android:layout_weight="4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"
android:gravity="bottom|left"
android:orientation="vertical">
<ImageView
android:id="#+id/body"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/body"
android:layout_gravity="bottom|left" />
</LinearLayout>
</LinearLayout>
Here you can see I have a parent linear layout, split into two children linear layouts. This is because I need the images to be positioned differently within that part of the page.
In a nutshell, I need logo to be vertically aligned to the top, and body horizontally aligned to bottom-left.
Now, a few things that I've tried:
Using RelativeLayout rather than Linear
Switching gravity with layout_gravity for both LinearLayout and ImageView, along with combinations of excluding each
Fairly confident match_parent for width and height is what I want, but I have tried different combinations with wrap_content
What I've come to understand:
gravity:top requires the parent view use orientation:horizontal
gravity:left requires the parent view use orientation:vertical
gravity applies to the children of the view
linear_gravity applies how the child aligns with it's parent
Using the same value for gravity on the parent and linear_gravity on the child might have the same effect (when using one instead of the other)?
Hopefully this is enough information. I'm having a very difficult time wrapping my head around how these layouts work.
Thank you SO much for the help!
I think your problem is you are setting dimensions of the image views to match_parent. I would use a RelativeLayout as it seems to be the most efficient in your case (pseudo-XML-code):
RelativeLayout (width=match_parent, height=match_parent)
ImageView (width=wrap_content, height=wrap_content,
alignParentTop=true, centerHorizontal=true)
ImageView (width=wrap_content, height=wrap_content,
alignParentBottom=true, alignParentLeft=true)
You don't need any gravity setting here. You might want to play with the scaleType attribute depending on your image sizes.

LinearLayout, RelativeLayout, etc. margins do not work as expected

Margins in group layouts do not seem to work.
For example,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
should display a button with 40p margins on all sides. However, it has 80p margins on the right and bottom.
Am I doing something wrong?
Is this a bug?
A workaround would be to use gravity, but this only works with even margins.
BTW, there is a similar question posted here but has not been answered.
android:padding="40dp" on the LinearLayout or android:layout_margin="40dp" on the Button will give you the effect you want. Padding defines the space between a views edges and its content, layout margin defines extra space on the sides of a view.
The problem is actually the way FrameLayout interprets margins. setContentView() attaches your "main" layout to a FrameLayout, which is the actual root of the view hierarchy (you can see that with Hierarchy Viewer) and is offered to you by the phone.
Margins are managed by the parent layout, so in this case that main FrameLayout. I don't know if it's a feature or a bug, but that's how this layout interprets margins.
So well, the solution was already posted while I was typing: use padding instead.
if you need set margin for a layout, simply wrap it with another linear or relative layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
</LinearLayout>
Wrapping the Linear Layout with another layout is the best strategy.

Categories

Resources