I get a warning saying: "Nested weights are bad for performance". I've literally copied this code from another layout, but in this one it gives an error and in the other one it doesn't.
<?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" >
<ListView
android:id="#+id/listWeighings_weighing"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:background="#000000" >
</ListView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/btnInsertMutation_weighing"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Mutatie invoeren" />
<Button
android:id="#+id/btnExecuteWeighing_weighing"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="weging uitvoeren" />
</LinearLayout>
</LinearLayout>
I bet it's a stupid error but can somebody please point out what I'm doing wrong?
You have to add weightSum to the linearlayout and remove the weight of the listview:
<?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" >
<ListView
android:id="#+id/listWeighings_weighing"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
android:background="#000000" >
</ListView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<Button
android:id="#+id/btnInsertMutation_weighing"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Mutatie invoeren" />
<Button
android:id="#+id/btnExecuteWeighing_weighing"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="weging uitvoeren" />
</LinearLayout>
</LinearLayout>
3 things to remember:
set the android:layout_width of the children to "0dp"
set the android:weightSum of the parent
set the android:layout_weight of each child proportionally (e.g. weightSum = "5", three children: layout_weight="1", layout_weight="3", layout_weight="1")
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#color/black"
android:orientation="horizontal"
tools:ignore="NestedWeights" >
Add this line to ignore Nested Weight problem which reduce the performance of layout.
If anyone else wishes to ignore NestedWeights, keep in mind you must also specify the tools in the header. For example
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/appDarkBackGround"
android:orientation="horizontal"
tools:context=".MainActivity"
tools:ignore="NestedWeights"
>
Related
I am doing an user interface in Android.
My idea is divide this interface in three equals parts (this is easy, three layouts with weight), but I want to put a images in interesctions of these layouts.
For example an image that overlapes some space in layout1 and layout2, and the same in 2 and 3.
How can do this? My code:
<LinearLayout 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="fill_parent"
android:orientation="vertical"
android:weightSum="1.0">
<LinearLayout
android:id="#+id/first"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.33">
</LinearLayout>
<LinearLayout
android:id="#+id/second"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.33"></LinearLayout>
<LinearLayout
android:id="#+id/third"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.33"></LinearLayout>
</LinearLayout>
And my idea: Android: Placing ImageView on overlap between layouts
Thanks
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="6.0" >
<LinearLayout
android:id="#+id/first"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/second"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/third"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="6.0" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:orientation="vertical" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/firstDividerLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2.0" >
<ImageView
android:id="#+id/firstDividerImageView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/secondDividerLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2.0" >
<ImageView
android:id="#+id/secondDividerImageView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0" >
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
Note that I wrapped your original LinearLayout in RelativeLayout and then I added another LinearLayout with 'dividers'. Dividers size is set by weights precisely so that it overlays your sections in the center.
This is the result (if you set red background for your 'second' layout):
Three options:
Make the view in between also percent. i. e. Each of your
LinearLayouts gets a weight of 0.30 and your views in between get a
weight of 0.05
Put the view on top of your LinearLayout 2 and 3 (not exactly same
height of each of them then)
Do it programmatically, in code set the height of each of them.
I'm trying to design something like that :
Currently i'm having issue putting the button at "the middle" of the two layouts reunion point. Is there a way i do this ?
Thanks.
Here is a way to do it
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="#FF0000">
<!-- TO ADD CONTENT HERE -->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="#FFFF00"
android:weightSum="0.5">
<!-- TO ADD CONTENT HERE -->
</LinearLayout>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#000000"
android:text="TEST"
android:textColor="#FFFFFF"/>
</RelativeLayout>
OUTPUT:
You can change the layout height from android:layout_weight="0.5"
you can use RelativeLayout for your parent and try adding twoLinearLayouts , one below another and set their heights, now place a Button in your RelativeLayout and set android:layout_centerInParent="true" for your Button .
and if you want to use weight for layouts, instead of adding two LinearLayout to your RelativeLayout, add one LinearLayout with weightSum=100 and then add two LinearLayouts to it with custom weights.
for your case , you have to do sth like this :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
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="20"
android:background="#f00" >
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="80"
android:background="#0f0" >
</LinearLayout>
</LinearLayout>
<LinearLayout
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="20" >
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="test" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
im trying to do this layout above
and here is my code
<?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="match_parent"
android:layout_weight="0.80"
android:orientation="horizontal" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:padding="10dp" />
<RelativeLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
In ImageView, i got the error "Nested weights are bad for perfomance". I would to understand why this happening and if someone have a better solution for this layout.
The layout_weight attribute is another way of specifying a width or a height in percentage dimensions, and to optimize the calculation of the dimensions you should use 0dp to one of them (the one you are replacing with).
Another optimize tip is to remove the <RelativeLayout></RelativeLayout> that is not being used in your layout.
Please try the solution below:
<?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="0dp"
android:layout_weight="0.80"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:padding="10dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.20"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
The error "Nested weights are bad for performance" happens because you have a weighted LInearLayout "nested" inside another weighted LinearLayout (see below). In order for Android to perform this it will have to draw the entire screen to get all of the non-nested layout measurements, then draw it all again to calculate the "nested" weighted layouts.
This can be a huge performance hit. However, I built one screen that had 4 layers of nesting and about 100 layouts, including lots of images. Rendering took about 5 milliseconds on newer devices, usually less. So this is really only an issue if you are frequently redrawing the nested layouts (like trying to animation with nested layouts). If you don't see a performance hit that you can measure in your logcat or observe while using your app, don't worry about it. Test thoroughly!
In other words, it's a warning, not an error.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.80"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:padding="10dp" />
<!-- THIS IS YOUR NESTED WEIGHTED LAYOUT -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.50"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.20"
android:orientation="vertical" >
</LinearLayout>
I would rather write it as below. Notice using integers instead of fractions:
<?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="0dp"
android:layout_weight="4"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="10dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
I need to create a horizontal layout as follows :
I can set the total width of the layout of C using android:layout_width="match_parent" but I'm completely stumped at setting the rest of the layouts. Any help is highly appreciated.
The whole app is set to run on a horizontal layout only, if that helps in decide what method to set the layouts.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="100" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="90"
android:orientation="horizontal"
android:weightSum="100" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:background="#FF0000" >
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:background="#00FF00" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:background="#FFFF00" >
</LinearLayout>
</LinearLayout>
The trick is to use LinearLayout's with a certain weight like 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:weightSum="10">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<View
android:id="#+id/view_A"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:id="#+id/view_B"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<View
android:id="#+id/view_C"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="9" />
</LinearLayout>
i want to put a linearlayout under a listview, if i put it above the listview i got an exception and the activity stop working suddenly, and when i put it under the listview it doesn't appear, what am i doing wrong?
<?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" >
<ListView
android:id="#+id/lvRestaurants"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
<LinearLayout
android:id="#+id/llButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/bDone"
android:layout_width="153dp"
android:layout_height="match_parent"
android:text="Done" />
<Button
android:id="#+id/bCancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>
Add android:layout_weight=1 to your ListView.
The reason why the other layout doesn't appear is because your listview takes all the place in the parent layout (android:layout_height="fill_parent")
I suggest using RelativeLayout instead. Using LinearLayout and specially android:layout_weight is expensive performance wise. This layout accomplishes what you need. The key is android:layout_alignParentBottom and andoid:layout_above properties. Try it out.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/llButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<Button
android:id="#+id/bDone"
android:layout_width="153dp"
android:layout_height="match_parent"
android:text="Done" />
<Button
android:id="#+id/bCancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Cancel" />
</LinearLayout>
<ListView
android:id="#+id/lvRestaurants"
android:layout_above="#id/llButtons"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</RelativeLayout>
you can try using weight Concept.
I did some changes in your code
<?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="10" >
<ListView
android:id="#+id/lvRestaurants"
android:layout_weight="8"
android:layout_width="fill_parent"
android:layout_height="0dip" >
</ListView>
<LinearLayout
android:layout_weight="2"
android:id="#+id/llButtons"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="horizontal" >
<Button
android:id="#+id/bDone"
android:layout_width="153dp"
android:layout_height="fill_parent"
android:text="Done" />
<Button
android:id="#+id/bCancel"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>
Do changes according to your requirement
To save the overhead, provide listView with layout_weight="1"
<ListView
android:layout_weight="1" // The MagicLine
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
and you LinearLayout with gravity="bottom"
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="horizontal">
// here will be views, you want to put with in your LinearLayout
</LinearLayout>
Also you can put a LinearLayout beneath a list view, would be the use of a Relativelayout.
Here is a sampleStructure.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="constantHeightofLinearLayout" /> // here the constant height of the linear Layout or buttons, should be inserted
<LinearLayout
android:layout_alignParentBottom="true" //this is the line, that would put this linearLayout beneath your Listview
android:layout_height="constantHeight" // this height should be the marginBottom of ListView
android:gravity="bottom"
android:orientation="horizontal">
// here will be views, you want to put with in your LinearLayout
</LinearLayout>
</RelativeLayout>