I'm trying to divide a page in three parts. I'd like to do it in percentage values, however that is not supported by Android. Instead I have to use android:layout_weight. But I have a hard time understanding it and getting it right. Especially how the actual size gets calculated. Is there a way to get a percentage value (0..100%) out of android:layout_weight?
I went through a few cases (see attached screenshot) to describe the problems. The colored fields are all <LinearLayout> with android:layout_height="fill_parent", because I want the full screen to be divided between those.
Case 1
Okay, simple. Every <LinearLayout> gets 33%.
Case 2
Ups?! The first (yellow) <LinearLayout> disappears completely? Why?
Case 3
Confused again. The yellow <LinearLayout> is back. However, the two first <LinearLayout> with the heavier weight get smaller? What is going on?
Case 4
I have absolutely no idea what the maths behind all this is.
Is there a way to get a percentage value (0..100%) out of android:layout_weight?
Sure. Make them add up to 100.
For your "percentage value", you want the android:layout_height of the individual items within the LinearLayout to be 0px.
When you use android:layout_height="fill_parent" for the bars, you are not leaving any available space. (Since they are filling the parent.) Because all 3 are set to fill, the requested height is actually 3x the parent height, so the weights are being applied to a negative remaining space. This explains the weird behavior you are seeing, and why setting layout_height to 0px solves it.
Related
There is a dialogue, in one place of which I need to show either one element or another, depending on the situation. Example:
I would like to do this so that the elements below do not move. I want to keep the area occupied by alternating elements of a constant size.
What is the easiest way to do this?
I can, of course, manually change the visibility. Вut when switching, if there is a different height, then the underlying elements will jump. I can manually set their height equal, but this is inconvenient. It will be necessary to correct the heights of all alternating elements every time after I change one of them.
For example, Qt has Stack Layout that allows you to alternate elements and takes the size of the largest of them. Does Android have something like this?
You might be able to use the ViewSwitcher to hold the two layouts.
It holds 2 different child views and measures its height to the biggest child by default.
Here's the documentation for it: https://developer.android.com/reference/android/widget/ViewSwitcher
Just an idea if you can't find something like Stack Layout. I haven't tried it.
You can put all the elements in an horizontal LinearLayout with MATCH_PARENT width for the visible one and 0 for the invisible ones, but keeping all of them VISIBLE. It should always have the largest height and only the MATCH_PARENT width element should actually be visible.
I am trying to have 3 LinearLayouts ordered horizontally (basically forming three columns) within another LinearLayout where the width of the middle layout can vary depending on it's content.
All columns should be visible at all times filling the viewport from left. The left and irght column will be assigned a max width. So only the size of middle layout varies. If the total width of all columns exceeds the viewport size the middle column must not overlap or push out the other columns. But instead it should use the remaining space.
I tried using layout weights but that would put the right column always on the right side and the middle column would fill up all the space even though it's content would not require that.
When I try to use a RelativeLayout as a container I either end up with all three columns overlapping each other or the first column disappears.
I thought the below code (only schematic for now, as I don't have access to the code atm) should work, but as written above the first LinearLayout does not show up. The last LinearLayout seems to be in place as desired.
<RelativeLayout>
<LinearLayout
android:layout_alignParentStart>
</LinearLayout>
<LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_alignParentEnd>
</LinearLayout>
</RelativeLayout>
Does anyone know how I can fix this? Please let me know if you need more detailed code examples etc. I will try to provide them as soon as possible.
I found a few other questions concerning this or similar topics but the solutions always used either layout weights or something like the code snippet above. So far I had no luck with those approaches, maybe because those questions where either for slightly different use cases or a few years old so that the api has changed in the mean time.
Any pointers are greatly appreciated :-)
Yes. You want to defined the center columns with a layout_width="0dp" and a layout_weight="1". The left and right columns will be layout_width="wrap_content".
A LinearLayout should contain the 3 inner "column" LinearLayouts.
I finally found a solution that works.
Using the layout_weight as describe by Jeffrey Blattman alone does only work when the views get large enough to fill the screen.
But as long as the views only fill a part you get gaps between them as the middle view fills up the remaining space. This is something I want to avoid in this case.
For some other reason I had to put my layout into a fragment. Now when I set the dimensions of the fragment to wrap_content the behavior is exactly as I want it. So the views do not get blown up while they are to small but are laid out as if there was no layout_weight defined. But still when growing larger the edge views stay within the screen.
I am working on a project that involves a letter filling up most of the height of the screen. At this point, the height of the letter is supposed to be 428 Pixels. The height of my screen is well over this, the layout (although a fragment) has ample room to fit the letter, and both the fragment layout and underlying layout are set to match_parent. For the textview itself, I have it centerInParent = true Trust me, I've been doing this a while so I know everything is correct as far as initialization goes, I just can't figure out why the letter wont appear! Oh, I should also note that although the screen can hold that size of a letter, it is tight (talking about approximately 50 pixels above and below), and that the entire activity and layout is set to a FullScreen theme, because I assumed it would give it more usable space. Any ideas? Thanks everyone!
EDIT: The total number of pixels I have in my display height of the monitor is 721, the letter takes up 428 pixels, after subtracting a few default-sized buttonss at the button that leaves me with about 260 pixels of free space. And as I mentioned there is no actionBar.
I found that I had to convert the textView using this code: txt.setLayerType(View.LAYER_TYPE_SOFTWARE, null); Hope this helps!
Why would someone use weights 2:4 instead of weights 1:2? I am looking through a Udacity course layout. It's a LinearLayout with two children views. and the children are given weights 2 and 4 respectively as opposed to 1 and 2. Why is that?
Because they wanted to? The actual values don't matter, the ratios are all that does. Usually when you see that its code that evolved over time, they originally had something in there with weight 1 and removed it (while weights don't need to be whole number, most people try to keep them that way).
I was just building some UI in xml, and Lint gave me a warning and said to set android:baselineAligned to false to improve performance in ListView.
The docs for the Lint changes that added this warning say
Layout performance: Finds LinearLayouts with weights where you should
set android:baselineAligned="false" for better performance, and also
finds cases where you have nested weights which can cause performance
problems.
Can somebody explain why this improves performance, specifically when weight is involved?
By setting android:baselineAligned="false" , you're preventing the extra work your app's layout has to do in order to Align its children's baselines; which can obviously increase the performance. (Fewer unnecessary operations on UI => Better performance)
how android:baselineAligned="false" help . It may not be the answer but help to get concept.
I've just managed to get 3 items (icon, text, button) centered
vertically in horizontal LinearLayout.
This may seem simple, but in reality specifying
android:gravity="center_vertical" as LinearLayout attribute is not
enough - icon is centered, but text and button are not. This is
because (presumably) text have a baseline, and centering algorithm
uses it instead of 'real' vertical center. But what is worse - button
(which comes next to text) is centered using text's baseline!
Specifying android:baselineAligned="false" in LinearLayout turns this
off, and everything centers correctly.
// Baseline alignment requires to measure widgets to obtain the
// baseline offset (in particular for TextViews). The following
// defeats the optimization mentioned above. Allow the child to
// use as much space as it wants because we can shrink things
// later (and re-measure).
if (baselineAligned) {
final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
child.measure(freeSpec, freeSpec);
}
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/LinearLayout.java#L1093