Misunderstanding Android weights - android

I've tried a couple different approaches with the weights, but obviously there is some glaring mis-understanding of how to get what I am aiming for here. Simply what I am attempting to do, is have the ImageView take up 1/3rd of the screen across the width, while having the layout of textViews take up the remainder of the 2/3rds of the screen across the width.
What ends up having as I try and manipulate it however, is that the ImageView is small and not taking up nearly the space that it should be. I've been messing around with trying to get the layouts right all morning.
The answer below has led me to the following which was what was occurring in this instance:
0dip layout dimensions
<?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:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/skeleton"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="2">
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

In linear layouts, there is a trick to make weights work - you should set dimension to apply weight to zero.
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/display_pro_skeleton"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="2">
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
Something like this.

There's nothing really tricky about weights at all. What using weights says is "measure all the views in my layout, then take whatever space is left over, and divide it according to their weights". Weights only affect leftover space. This is why setting the dimensions of all the views to 0dp works, because in that case, all the space is leftover space.

Weights are somewhat counter-intuitive at times. Try using decimals so the big one will be .66 and the small one will be .34. There are many examples out there that use whole numbers but I believe that in most cases it is better to use numbers between 0 and 1.
EDIT: So I just looked a little more at your xml and realized it's probably more because of the width and heights you are using. For best results with weights you should use "fill_parent."

Related

Children views having equal height

I have a horizontal LinearLayout with two buttons with text inside.
The LinearLayout's and the buttons layout_height is wrap_content.
The text of one of the two buttons takes two lines unlike the other's which takes one line.
So at the end one of the buttons has a bigger height than the other which is something that I don't want.
I know how to solve this programmatically. So the reason I making this question is to know whether I can solve this through xml.
One possible solution is, for the button whose text is one line, set
layout_height="match_parent"
and it works fine.
But the problem here is that generally I don't know which button will occupy the biggest height.
In essence what I want to do is: having a LinearLayout with Views inside
I want to set the height of all the children Views to be equal to the height of the View which when has its content wrapped has the max height.
And the question is if this is possible through xml?
An example XML. Also I forgot to add that I already have 0dp in the widths.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/some_string" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/some_other_string" />
</LinearLayout>
I guess what you search is android:baselineAligned="false", this will avoid that the text are on the same baseline and the buttons will start at the same y position on the screen.
Here without android:baselineAligned="false":
And here with:
However if you also want that both buttons are equal sized try this layout example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="aaaaa"/>
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="bbbbbbb bbbbbbbb bbbbbbbb bbbbbbbbbbbb bbbbbb"/>
</LinearLayout>
That will look like this:
Use this thing to set weigh Sum and weight layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button 1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button 2" />
</LinearLayout>
</LinearLayout>

How can I create this layout in Android?

I've been trying to recreate this layout in Android Studio (API 19) without success.
I added at the top part of the image what I need without texts on it, the part below has some explanations.
Every time I tried (no matter LinearLayout or GridLayout), the text in the middle broke the design if it is long or if I do not set real DP size (like using wrap_content), if the text has a fixed size I must adapt it to every screen size on both, vertical and horizontal, which I don't want, because I must update a lot of files it every time I make changes on layouts, and if it has wrap_content and the text is long the switch goes off of the screen.
I made this "design" with Photoshop of what I need to recreate on Android Studio on a layout (xml only, not programmatically), if possible I'd like LinearLayout or GridLayout or both, I don't care how much sub-layouts are needed.
Additional: If someone knows how to get that switch style for older versions of Android, it'd be really good to get the same style on that too, but is not necessary.
Please help me, I really can't make it, thanks a lot.
With a Relative Layout this kind of design wont be a problem.
You will need to use the properties android:layout_alignParentRight and android:layout_alignParentLeft.
Your center textview will use android:layout_toRightOf and ndroid:layout_toLeftOf.
More informations : Relative layout documentation
Use following XML as your layout codes, this is exactly what you want on your designs
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="#drawable/icon_paypal"
android:layout_margin="16dp"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/switchlayout"
android:layout_toRightOf="#+id/image"
android:layout_marginTop="16dp"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Text 1"
android:textColor="#000"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Text 2"
android:textColor="#ccc"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/switchlayout"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="16dp"
android:paddingLeft="16dp"
android:gravity="center"
android:layout_height="72dp">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Use Follow XML code. it will fit in any screen
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".2"
android:gravity="center">
<ImageView
android:layout_width="40dp"
android:layout_height="wrap_content"
android:src="#drawable/app_icon" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".6">
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".2"
android:gravity="center">
<Switch
android:layout_width="40dp"
android:layout_height="wrap_content" />
</LinearLayout>

Android: Layout Problems with LinearLayout

I must be doing this all wrong, and layouts confuse me, so I hope someone might guide me in the right direction. This whole thing is a mess because I've been fiddling with it non-stop since I created it a month ago, trying to fix little issues here and there, so I apologise quite a lot in advance for this disaster.
Literally all that I want is a LinearLayout where everything is centred horizontally and vertically.
This is how it shows up in my Design page.
Before I dump in my layout, allow me to explain what's going on.
I have a TextView that shows status messages above the ImageButton. Below the ImageButton, I have a TextSwitcher and finally a circular ProgressBar.
I've had to put android:adjustViewBounds="true" and android:scaleType="fitCenter" on my ImageButton because the image is much bigger than would fit, otherwise.
Anyway, here's the dump. Hoping someone might be able to make suggestions.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:orientation="vertical"
android:layout_gravity="fill_vertical|center"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="nosensor"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.gesslar.threshvote.MainActivity"
android:background="#color/colorFaded"
tools:showIn="#layout/activity_main">
<TextView android:id="#+id/textStatusMessage"
android:textColor="#color/colorText"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<ImageButton android:id="#+id/buttonVote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:src="#drawable/ic_vote_button_image"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
android:onClick="onVotePressed"
android:layout_gravity="center_horizontal|center_vertical"
android:adjustViewBounds="true" />
<TextSwitcher android:id="#+id/textCountdown"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:textColor="#color/colorText"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="#dimen/countdown"
android:includeFontPadding="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ProgressBar android:id="#+id/loadingBar"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_gravity="end"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
android:indeterminate="true"/>
</LinearLayout>
If you still like using LinearLayout, you can order your layout like this to have a layout center both horizontally and vertically
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0ff"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Button Center Vertical/ Horizontal" />
</LinearLayout>
</LinearLayout>
Or simple use RelativeLayout with android:layout_centerInParent="true" to have a layout center both orientation
Hope this help
First of all, LinearLayout can either store everything horizontally or vertically but not both at the same time. So you have to choose specially what do you want. If you want everything to appear in vertical fashion but still some components, say TextView needed to be in a horizontal layout, you may wish to use another LinearLayout (nested inside the main LinearLayout and give it an orientation : Horizontal ).
Apart from this, I don't think there is any problem with that Layout or I did not understand your problem properly, either one.

How to refresh match_parent in a linearLayout after using setRotation?

I have several nested layouts that I'm trying to rotate 90 degrees on demand in code. I've got the setRotation part of things working just fine, but unfortunately things aren't resizing quite right with the rotation. The width on these elements is set to match_parent, and after the rotation it's still matching the parent width, not the parent height that it should be matching.
XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="link.basiclifecounter.LifeCounter"
android:background="#CC00CC">
<LinearLayout
android:id="#+id/topPlayers"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical"
android:background="#CC0000">
<RelativeLayout
android:id="#+id/p3"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
**A bunch of stuff in here**
</RelativeLayout>
<RelativeLayout
android:id="#+id/p2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
**A bunch of stuff in here**
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/bottomPlayer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="#00CC00">
<RelativeLayout
android:id="#+id/p1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
**A bunch of stuff in here**
</RelativeLayout>
</LinearLayout>
</LinearLayout>
Rotation Java Code
view.findViewById(R.id.topPlayers).setRotation(90); //Rotate the entire top box
view.findViewById(R.id.p3).setRotation(180); //Flip one side so both players face outwards
This picture shows the image before the rotation occurs.
This picture shows the image after the rotation occurs.
As you can see, the entire box has been rotated after it's height and width are already set. In the unrotated version the width (match_parent) should be full screen and the height (layout_weight=2) should be 2/3rds of the screen. That works just fine. The problem is after it rotates, those sizes stay the same instead of adapting and changing to the new rotation.
I threw in some bright background colors to help troubleshoot, that Pink that you're seeing is in the main LinearLayout, not in any of the layouts that are rotated.
I did try including the rotation in the xml itself, instead of within the code, and got the exact same results as the after picture, so it's clearly something I don't understand about how to get the layout widths the way I want. Can I just not use layout_weight effectively with rotation?
I think that you are having the same issue as outlined in this Stack Overflow question. It appears that the rotation is simply not taken into account for layout purposes. In other words, layout occurs then the rotation happens with the views as laid out prior to rotation.
This answer to that same question may help you.
You could also manually adjust the measurements. Either way is a little messy, but I think that is the way it is.
You could load an alternate layout that will behave as you wish instead of doing the rotation. (See layout and image below.) You can also be achieve the same result by changing the layout parameters programmatically.
Here is a project on GitHub that demonstrates doing the rotation programmatically. The view rotates after a three second pause.
I hope that you find this useful.
alternate.xml
<LinearLayout
android:id="#+id/topPlayers"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:background="#CC0000"
android:orientation="horizontal">
<RelativeLayout
android:id="#+id/p3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:rotation="90">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="p3"
android:textSize="48sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/p2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#0000CC"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="-90"
android:text="p2"
android:textSize="48sp" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/bottomPlayer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#00CC00"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/p1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="p1"
android:textSize="48sp" />
</RelativeLayout>
</LinearLayout>

Combine layout_weight with minWidth

I have a layout which I want to split into 2 views using layout_weight (1:2). But, I want the left view to have at least 400dp width.
For example, if the left view gets 420dp width by using weight then leave it, but if it has less than 400dp, than let it be 400dp and give the other view all the rest.
This is the layout I've tried and did not work for me.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="400dp"
android:background="#android:color/holo_blue_bright"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#android:color/holo_green_light"/>
</LinearLayout>
Please help,
Thanks!
I think this is what you need:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<View
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="400dp"
android:background="#android:color/holo_blue_bright"/>
<View
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#android:color/holo_green_light"/>
</LinearLayout>
Basically, let the first layout take the needed space but no less than 400dp. The second one will take all the remaining. As with all the cases when weight is involved, be sure that the needed space (for width) for the 2 children is less than what the parent can offer, otherwise you will have things off screen.
Note: I tried it on phone layout, but 400dp was off screen in portrait so it seemed like the first layout was taking all the space, so please make sure to try it out on a device with more than 400dp in the direction you want your layout span :-)
Try this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:weightSum="3" >
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:color/holo_blue_bright"
android:minWidth="400dp" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#android:color/holo_green_light" />
</LinearLayout>

Categories

Resources