Android layout with error "Nested weights are bad for perfomance" - android

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>

Related

Android Layout with height in percent

I want to make layout like that:
But I don't know how to make panel 2 and 3 filling remaining space (after adding fixed size panel 1) in 50:50 ratio. There must be something I am missing or just don't know about Android layout, but what is it?
I forgot to mention that I want to use Constraint Layout for these panels. I use Android Studio.
Use a LinearLayout and layout_weight
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="2">
<View
android:layout_width="match_parent"
android:background="#color/blue"
android:layout_height="16dp" />
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/black"
android:layout_weight="1"/>
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/red"/>
</LinearLayout>
The Views can be changed to ConstraintLayouts
<?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">
<RelativeLayout
android:id="#+id/panel1Layout"
android:layout_width="match_parent"
android:layout_height="100dp" />
<LinearLayout
android:id="#+id/otherPanelContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/panel1Layout"
android:orientation="vertical"
android:weightSum="2">
<RelativeLayout
android:id="#+id/panel2Layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<RelativeLayout
android:id="#+id/panel3Layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

Put elements between layouts [ANDROID]

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.

Android and weight

Why does the following code only display two colors and not three? How would one fix this?
<?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="6"
>
<LinearLayout
android:background="#00ff00"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="3" />
<LinearLayout
android:background="#ff0000"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="2" />
<LinearLayout
android:background="#0000ff"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1" />
</LinearLayout>
Change the layout_height in each of the LinearLayouts to be 0:
android:layout_height="0dp"
Any other height gets in the way of Android's calculations for how much space to give to each layout based on the weights.

android how to create multiple equal sized elements without linear layout

I need to create a layout that contains 16 equally sized FrameLayout elements. I've seen lots of replies about this and how "Nested layout weights are bad for performance." What is a better way to solve this problem and still have the advantages of dynamic sizing of elements.
Thank you
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4"
android:orientation="horizontal"
tools:context="${packageName}.${activityClass}" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="4"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="4"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="4"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="4"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
</LinearLayout>
Mostly I just wanted to say thanks for the suggestions. I spent a week or more trying to find a solution that worked and finally decided to go ahead with development and see what the performance was like. The main problem was that I wanted the app to work on multiple devices and resize/handle orientation change and I couldn't find any suitable solution.
At this point everything is working. In landscape mode I have 2 columns x 3 rows that contain 18 equal sized cells each with an image and frame. Performance seems to be ok on everything I've tried from a cheap cell phone and generic 7" tablet up to a nexus-7.
What about using a GridView? You might have to google a bit so figure out how you can make the items resize according to the screen width, but i think it's possible. TableLayout would work too, but GridView seems to be cleaner.

nested weight in linear layout

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"
>

Categories

Resources