I would like to create this simple layout:
I wrote this:
<?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"
android:background="#color/purple_200">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"
android:background="#color/black" />
</LinearLayout>
But doing so I don't see any black view appearing. What am I missing?
There is a new way called ConstraintLayout which is preferred. You can use layout_constraintHeight_percent property of it.
Example
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/purple_200"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Output:
All you have to do is to add
android:weightSum="1"
to your parent's layout, so
<?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"
android:weightSum="1"
android:background="#color/purple_200">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"
android:background="#color/black" />
</LinearLayout>
I suppose you thought it's 1 by default, but it's not, you have to specify it, otherwise, it's calculated as the sum of the children's weights, so in this case, it was 0.3.
From the android:weightSum's definition:
Defines the maximum weight sum. If unspecified, the sum is computed by
adding the layout_weight of all of the children. This can be used for
instance to give a single child 50% of the total available space by
giving it a layout_weight of 0.5 and setting the weightSum to 1.0.
Other solution is androidx.constraintlayout.widget.Guideline. You can add a guideline to a constraintLayout, and you can change app:layout_constraintGuide_percent variable between 0..1 range. You can change orientation too.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
Related
I tried this answer.
But I get Nested weights are bad for performance. Is there anyway to solve this or should I continue with this warning?
Here is the layout necessary to solve this with ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<View
android:id="#+id/one"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#333"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/two"
app:layout_constraintBottom_toTopOf="#id/three"/>
<View
android:id="#+id/two"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#444"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/one"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/four"/>
<View
android:id="#+id/three"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#555"
app:layout_constraintTop_toBottomOf="#id/one"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/four"
app:layout_constraintBottom_toBottomOf="parent"/>
<View
android:id="#+id/four"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#666"
app:layout_constraintTop_toBottomOf="#id/two"
app:layout_constraintStart_toEndOf="#id/three"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
However, that performance warning is safe to ignore. Nested weights are bad for performance, but this will only be noticeable when you have lots of nested weights on many views all being updated frequently (e.g., flinging a RecyclerView where each item uses nested weights).
You can try this bunch of xml code below: (I've tested it no warning...)
Here is the main content xml file, test.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:weightSum="2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/test_1"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
<include
layout="#layout/test_2"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
</LinearLayout>
As I used same xml code for the two nested files test_1.xml and test_2.xml; I am sharing the common code below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:weightSum="2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#color/colorAccent"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#android:color/holo_purple"/>
</LinearLayout>
And guess what, I found a responsive layout as you want to achieve.
Here is the output:
You can use ConstraintLayout with guidelines. For example, if you want the layout split into 4 equal parts horizontally, you'd use 3 vertical guidelines, one set at 0.25, one set at 0.50 and one set at 0.75. If you want it split vertically, you'd use the same guideline percents but with horizontal guidelines.
You would then position your views with constraints to the guidelines and the parent.
I have two constraint layouts in a linear layout. I want the constraint layouts to occupy 30% and 70% of the screen respectively on all devices. What attribute inside the Linear Layout do I need to set in order to achieve this?
This should give the desired result. Setting a weightSum attribute to the parent linear layout and then accordingly giving the weights helps
<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="1" >
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"/>
</LinearLayout>
You have to take Parent Layout as ConstraintLayout and then after you have to use GuideLine to set 30 and 70 percent of screen.
<?xml version="1.0" encoding="utf-8"?><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_green_light"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
Output
Use WeightSum attribute on LinearLayout to achieve the Output you are expecting, Which is more easier than other methods.
<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="3" >
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3">
//Child layouts on 30% of layout
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7">
//Child layouts on 70% of layout
</android.support.constraint.ConstraintLayout>
If you want make something like that use
android:layout_weight="any number"
but you must make the same height for the both of them it doesn't matter if the height wrap_content or match_parent
The layout will occupy more form screen if the number less than the other one
I'm trying to create a layout of a list which starts on the bottom of a button and it's 3/4 of screen's width.
Just like this:
First, I used nested Linear layouts a horizonal and a vertical one, but then I read here that Constraint layouts are more responsive and I was impressed and gave it a try.
So, I tried to replace the outer layout to a constraint layout but now, I can't constraint the list to start at the bottom of the button and it starts at top of the screen.
I tried to see what would happen if I replaced the whole linear layout with a button just to see that the attributes are correctly implemented and it worked, so I understood that the Constraint layout does'nt effect the sons of the Linear layout although it should be effecting the whole layout (as I see it).
my code is the following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
My current layout looks like this:
I really appriciate the helpers!
You need to change layout height of linear layout to 0dp, I will put here the layout for you. Also consider migrating to androidx :)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I think, that using match_parent as width or height of child and adding any constraint is wrong here.
Edited xml (change margins if you want):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="24dp"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="24dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button"
app:layout_constraintWidth_percent="0.75">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
my name is Josh. I am trying to achieve the below layout in Android but I can't seem to split the inner layout to get the layout I want. Can someone help please.
This is what I have so far:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.firstapplication.myapplication.MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/imageView" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Name"
android:ems="10"
android:id="#+id/editText" />
</LinearLayout>
</RelativeLayout>
The only problem I am having is, I can't figure out how to split the layout as shown in the picture.
You can solve this multiple ways. I don't know the requirement for your layout but you really don't need two LinearLayout to solve this. However, with what you have currently all you have to do is give your first LinearLayout an id, and set the height to wrap_content like so:
<LinearLayout
android:id="#+id/LL1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
then in your second layout set the positioning to be below your first one, set the height to wrap_content and remove layout_alignParentTop otherwise your second layout will overlap to your first. So you have something like this for the second:
<LinearLayout
android:layout_below="#id/LL1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
This will put the second layout underneath the first, but the sizing will vary unless the first layout is always a constant height.
If you know you always want a 70:30 ratio regardless of the first layout height, you can use layout_weights instead. I can add that in if that's what you're looking for instead.
To have a constant ratio, change your root layout to be LinearLayout instead of RelativeLayout then set the orientation to be vertical and a weightSum to 1.
Then set your first LinearLayout to be a layout_weight of 0.7 and your second LinearLayout to be a layout_weight of 0.3. Like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:orientation="vertical">
<LinearLayout
android:id="#+id/LL1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"></LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"></LinearLayout>
</LinearLayout>
Set the LinearLayout's height parameters accordingly to achieve the desired ratio between two layouts.
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="**XYZ dp**"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
I think I have some problems with a LinearLayout container. I do not know how to fix these problems:
I am a beginner to XML but I think the problem is in the second LinearLayout. I hope someone can help me out.
The code is here below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
**<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
andriod:orientation="horizontal" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>**
<Button
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</LinearLayout>
The problem I see when reading your xml file is that inside the main LinearLayout you have 3 elements with the properties about the width and height as follows:
android:layout_height="match_parent"
android:layout_width="match_parent"
which means you expect the elements to fill entirely the main LinearLayout. This is not going to work. A linear layout has ordered not overlapping elements (RelativeLayout is there for that). Since the main LinearLayout is supposed to be oriented vertically, I suppose that for these three elements, you need to set the properties to match the whole width of main LinearLayout and to be wrapped vertically, by setting these values:
android:layout_height="wrap_content"
android:layout_width="match_parent"
You should apply these to the TextView, LinearLayout and Button elements of second level.
If you have overlapping imageviews try adding weights to them and/or changing the width to not match the parent and only wrapping the content.
please change andriod to android ( Line 14 )
Your posted code has a typo. Your fix might be as simple as replacing the line:
andriod:orientation="horizontal"
with:
android:orientation="horizontal"
Judging by the image you posted, I think you may have forgotten to add weights to occupy the free space in your Linearlayouts. Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
andriod:orientation="horizontal"
android:layout_weight="1" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
</LinearLayout>