I am new to Android and I am designing a layout using LinearLayout where I want all the three buttons to take equal spaces on the LinearLayout.
I did it by giving them equal width but then they do not cover the whole length. Is there a simpler approach to it?
welcome to Android Dev. I am sure this might be a duplicated question and would advise you to search through previous answers before putting a new one.
But let me tell you how you can achieve this is a simple application of weight in layout
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:weightSum="3">
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Button 1"
android:layout_weight="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Button 2"
android:layout_weight="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Button 3"
android:layout_weight="1"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
As you can see above the weightSum tells the Linear layout the total weight of items in the layout below
android:layout_weight="1" is a weightage of each element in the layout. So there are three buttons and each have a weight of 1, which adds to 3 of the Linear Layout. So each button will be allocated the same space. You can play with weights to give different spaces to different views inside the Linear layout. You can leave the weightSum attribute and the linear layout can calculate on its own too based on the children's sum of the weights.
So you see this is a kind of relative spacing given to the Views based on the weights they carry. Hoping this was helpful to you and what you were expecting to know.
EDIT: As pointed out by Primoz,it is better to have android:layout_width = "0dp" so that your team or other persons can better understand the width controlling View.
It's hard to say anything without code sample, but most likely you are missing layout_weight attribute.
Here's an example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 2" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 3" />
</LinearLayout>
Related
I have a LinearLayout and its XML is:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"
tools:context=".MainActivity">
<Button
android:id="#+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="Button" />
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="Button" />
</LinearLayout>
and it is the result is:
as you can see the top left button has a little margin from top but as the code shows there are no margins.
why is this happening?
also there is a weird solution which is if you set gravity:top to all buttons you will get the expected result. but why is it even needed because linearlayout(horiz) should start adding items from top left to top right.
I was referring some documents and SO threads to look for the solution as the question seemed very intresting to me.
Finally I have found out the reason.
A horizontal LinearLayout aligns the baselines of all its child controls by default. So the first line of text in your multi-line button is vertically aligned with the single line of text in the other buttons.
To disable this behaviour, set android:baselineAligned="false" on the LinearLayout.
All credit goes to #Karu for this answer : https://stackoverflow.com/a/8290258/4211264
This is due to text wrapping in first button. Other two buttons take too match space on screen. And first button try's to stay on screen by self wrapping. I don't know what is your task. If you want to keep buttons in one line try to use layout_weight = 1 on all buttons.
This is because you have given different weights to every button. You need to give equal weight to every button. Replace your layout file code with this.
<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="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"
tools:context=".MainActivity">
<Button
android:id="#+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
Consider the following diagram:
The blue buttons are buttons and the red is a textview. I am trying to place them side by side as shown in the diagram but am having confusion because the app should be compatible with different screen sizes and densities.
Basically I want all the buttons to be of the same sizes(square typically) and TextView larger and say when the screen gets bigger(e.g. rotating) only the middle(red) textView should expand and the button size should be the same while they stay in their positions.
what I have tried
I tried using LinearLayout with layout_weight set accordingly but
for bigger screensizes the buttons(blue) would also scale in
proportion of their layout weight, and they'd not look square.
It'd be easy doing this using constraint layout but, it requires
hardcoding the button size(sizing the button in the design editor
does this), which I don't think is a good idea because if screen get bigger button would be smaller.
I could also take a certain percentage of the screen width and apply it to the button size, but how do I make sure that icon for the button renders okay with the scaled buttons and the buttons are aligned as so:
i.e. their centers are aligned but different in height, equidistant from each other.
also I'd have to do that programmatically instead of using the design editor or the xml.
So for this type of purposes what layout should I use and how should I set up my views?
If you want this design in xml, then try this
Note : Use the dimensions from dimens folder for different screen size. Here for LinearLayout of TextView Height use from dimens folder
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:background="#color/colorPrimary"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:weightSum="0.9">
<Button
android:layout_width="0dp"
android:background="#color/colorAccent"
android:layout_weight="0.1"
android:layout_height="wrap_content"
android:layout_margin="2dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="100dp"
android:layout_margin="2dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff00ff" />
</LinearLayout>
<Button
android:layout_width="0dp"
android:background="#color/colorAccent"
android:layout_weight="0.1"
android:layout_height="wrap_content"
android:layout_margin="2dp"/>
<Button
android:layout_width="0dp"
android:background="#color/colorAccent"
android:layout_weight="0.1"
android:layout_height="wrap_content"
android:layout_margin="2dp"/>
<Button
android:layout_width="0dp"
android:background="#color/colorAccent"
android:layout_weight="0.1"
android:layout_height="wrap_content"
android:layout_margin="2dp"/>
</LinearLayout>
</LinearLayout>
Use linear layout and use layout_weight only to TextView and for Buttons give fix width
e.g.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent">
<Button
android:layout_width="#dimen/length_50"
android:background="#color/colorPrimary"
android:layout_height="#dimen/length_50"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:background="#color/colorAccent"
android:layout_height="#dimen/length_50"/>
<Button
android:layout_width="#dimen/length_50"
android:layout_marginEnd="#dimen/_10dp"
android:background="#color/colorPrimary"
android:layout_height="#dimen/length_50"/>
<Button
android:layout_width="#dimen/length_50"
android:layout_marginEnd="#dimen/_10dp"
android:background="#color/colorPrimary"
android:layout_height="#dimen/length_50"/>
<Button
android:layout_width="#dimen/length_50"
android:background="#color/colorPrimary"
android:layout_height="#dimen/length_50"/>
</LinearLayout>
and result
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>
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."
I'd like to have two adjacent views, a first that is a fixed size and a second that adjacent to the first that uses the remaining space.
I could easily do this with LinearLayout and weights, but I would like to avoid the "nested weights are bad for performance" problem.
Is there another layout type that can accomplish the equivalent? Please provide an example if so.
A RelativeLayout could do what you want, for example:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/button1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Button"
android:background="#99cc00" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/button1"
android:text="Button"
android:background="#0077cc"/>
</RelativeLayout>
The first Button will be 200dp in width and the second will stretch to fill the rest of the parent's remaining width.
You could also use a RelativeLayout to split two views in equal sizes to avoid having double weights on some layouts.
I believe this could be done with a RelativeLayout. Example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#id/button">
...
</LinearLayout>
</RelativeLayout>
You can try
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="view with fixed size " />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="view with remaining space" />
</LinearLayout>
this is how weight works in LinearLayout:
At first, it will deduct the fixed dimension, then according to the weight, divide the available space, assign to the views which specify the weight attribute