LinearLayout should fill minimum space - android

I have this layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="left">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some text" />
</LinearLayout>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"/>
</LinearLayout>
But if in first text view (that in LinearLayout) is a lot of text, second text view goes off the screen. This can be solved by setting android:layout_weigh="1" to linear layout. But in this case linear layout will fill all space, and I need that linear layout fill minimum space when in it short text, and not hiding second text view when in linear layout a lot of text.

If the first textview occupies too much horizontal space, the second textview is rendered outside the screen...
To avoid rendering the second textview outside the screen, you need to limit the horizontal size of the first textview. You could give the first textview an android:layout_width with a fixed numeric value. You could set android:singleLine to false. You could set android:maxWidth to an appropriate value. (I haven't tried these solutions, but they should work).
Alternatively, you may consider using a single textview instead of two in a row.

A solution is to put your first TextView in a ScrollView, and put your second TextView in a fixed footer which will never be hidden (this can be done with a RelativeLayout).
If you have too much text in your first TextView then you will be able to scroll it while still showing the second TextView.

Related

In XML Button size changes with its Font size

I know this sounds simple but I wanted to change a button's font size to fill the Button .Even though the text doesn't take all the space inside the button when I decrease text height for example the Button's height decreases as well.Is there any way I can change The text-size so it fills that space inside the Button or do I have to just use an Image Button .
Here is the case :-
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#android:color/black"
android:id="#+id/led"
>
<Button
android:id="#+id/grow"
android:layout_width="match_parent"
android:layout_height="39dp"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:textSize="15dp"
android:background="#color/Lightbrown"
android:text="A▲"
android:textAllCaps="false"
/>
<Button
android:layout_width="match_parent"
android:layout_height="39dp"
android:text="A▼"
android:textAllCaps="false"
android:id="#+id/shrink"
android:background="#color/Lightbrown"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:padding="0dp"
android:textSize="10dp"
/>
See I used my Linearlayout as a background for my Buttons the second button's size changes with its font size I just want its size to remain the same as the first Button but with a smaller textsize.
Update
Your second button is not actually smaller, it is just aligned in a way you wouldn't necessarily expect.
Horizontal LinearLayouts with TextView (or subclass, which Button is) children will "baseline align" the children. That means they will make sure that the bottom edge of all the text in the row is at the same height. Since your second button uses smaller text, the text bottom would be higher up inside the button, so the LinearLayout forces the whole button down to accomodate.
Add this attribute to your LinearLayout:
android:baselineAligned="false"
Original
First, I assume you're using android:layout_height="wrap_content". If you don't want your button's height to scale with font size, you'll have to change this to some fixed value (or match_parent if you want it to be the same size as its parent).
As for why the text "doesn't take up all the space", that's because Buttons have padding built into them automatically. You can remove this padding by defining android:padding="0dp"
However, you'll soon notice that the button looks really bad if you give it no padding and too-large text. How to solve that is really up to the requirements of your design.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_gravity="center_horizontal"
android:padding="0dp"
android:textSize="36sp"
android:text="Hello world"/>
</FrameLayout>
Use a fixed size instead of wrap_content for your button.
f that doesn't work for your design, consider overlaying a TextView on top of your Button (with ConstraintLayout or FrameLayout or RelativeLayout). After that, you can set the TextView's focusable, focusableInTouchMode, and clickable properties to false so that it doesn't intercept your Button's clicks.

Why my TextView under an ImageView is not showing

I am writing an Android game. In the level selection activity's layout file, I want to layout the levels' buttons (They are actually ImageViews) like this:
x x x
x x x
And each level button has a TextView, with that level's name as the text, below it (Let's call these two views together as a "level choice"). I used a lot of LinearLayouts to do this. Here is the code for a level choice:
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_weight="1">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/angles"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/angles_level"
android:textSize="#dimen/level_text_size"/>
</LinearLayout>
As you can see, the two views' height and width are all wrap_content. But when I look at the designer, the text view doesn't show up.When I select the text view in the component tree, it shows where the text view is:
P.S. The picture isn't showing all six levels because I haven't made them yet.
As you can see, the text view is right at the bottom! When I select the ImageView, it shows that it is occupying all the space of its parent!
I don't know why this is happening, my image is certainly a square! Can you explain why this is happening and how do I fix it?
If you need my whole layout code, feel free to tell me in the comments.
For me, the best solution is to position and size it properly by code (where you have total control) instead of xml.
Anyway, i think your problem can be solved by setting ImageViews ScaleType
imageView1.setScaleType(ScaleType.FIT_START);
By XML:
android:scaleType="fit_start"
Hope this helps.
I use background color for textview when I'm studying the layout.
If you use wrap content in both dimension for TextView, that is invisible since you did not write any text inside it. wrap content means that the view take the minimum space. And no text means 0px; try to set ImageView and TextView with layout_weight 1 and layout_height 0dp. In this way both view take half of space of parent layout
Because right now, your LinearLayout doesn't know how to distribute the ratio of its children. And in fact, your imageview's wrap content already
consumes the whole space.
So, LinearLayout says "Sorry TextView, you have no space left".
Use layout_weight to both of the children.
I guess you want to have your picture twice the size of your text.
2:1
That is,
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_weight="1">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=2
android:src="#drawable/angles"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=1
android:text="#string/angles_level"
android:textSize="#dimen/level_text_size"/>
</LinearLayout>
I just realized that I posted a question about ImageViews leaving out too much whitespace:
LinearLayout leaving out too much white space. Why?
I think this is the same as that problem. So I tried setting adjustViewBounds to true in the xml. And it works! Now the image view look like this:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/parallel_lines"/>
You can use relative layout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/angles"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/angles_level"
android:textSize="#dimen/level_text_size"/>
</RelativeLayout>
or simple you can set background of textview to that image by putting this
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/angles_level"
android:background="#drawable/angles"
android:textSize="#dimen/level_text_size"/>

match_parent not performing as expected

I imagine this should be a fairly easy one to answer, if you understand XML Layouts better than I do that is. I don't seem to get what I was thinking I should when using the match_parent layout_height.
I have a LinearLayout root element with android:orientation="vertical". Inside this LinearLayout I want three elements:
- TextView
- ListView
- TextView
For both the TextViews I set android:layout_height="wrap_content" so that they will be only as tall as is necessary to display their contents. The thing is, I want the one TextView to sit at the top of the form, the other one to sit at the bottom of the form while the ListView fills up whatever space is available on the form. So here is what my xml layout looks like:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Top TextView" />
<ListView
android:id="#+id/listView_Species"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Bottom TextView" />
But it doesn't work. Here's what I get. I've selected the ListView so that it will be highlighted. Notice how it extends all the way to the bottom of the form, pushing the bottom TextView off the form.
When I change the layout_height property of the ListView to some fixed value, like 180dp, this is what the form looks like. I'm just posting this to prove that the bottom TextView is there but I still don't know how to get it to be fixed to the bottom of the screen while the ListView takes up whatever space remains, but in between the two TextViews.
Thanks in advance.
While the other answers try to fix your problem (which they don't actually--they suggest you do something that looks similar but may or may not look good on different devices), no one has filled in the gaps in your knowledge of LinearLayouts and match_parent. And these gaps are very common--Google's documentation is still far below stellar.
First, how do Views work within a LinearLayout? Let's go through the process of drawing a LinearLayout, using orientation="vertical" for simplicity.
Examine the height of the first child of the LinearLayout (LL for short). If the height is match_parent or fill_parent (old name for the same thing) then the height of the View is stretched to fill the entire viewing area. If the height is wrap_content, then measure the vertical space the View takes and use that space for the View. If the height is a non-zero number, use exactly that many pixels for the View's height (may clip if too small). If the height is 0 see below.
Put the next view below the view in 1. Check its height and act accordingly.
Continue for all the Views. If a View is pushed off the bottom, go ahead and stop calculating because no one will see it or any succeeding Views (assuming no ScrollView).
If the height of a View is 0, check it's gravity. This requires a second pass, storing the gravity of all the views and then allocating their heights proportionally. As you can guess, the second pass doubles the time layout takes, which isn't significant for simple layouts.
Explanation of your example: The first child of the LL (the first TextView) is measured and takes a certain amount of pixels. Then your ListView takes all the remaining space (via match_parent). And then your second TextView is not drawn at all as it's off the bottom of the screen. Which is pretty much what you observed, but now you understand why.
Solution: Use RelativeLayout. Works perfectly in this case.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/top_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="30sp"
android:text="Top TextView" />
<TextView
android:id="#+id/bottom_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="30sp"
android:text="Bottom TextView" />
<ListView
android:id="#+id/listView_Species"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/top_tv"
android:layout_above="#id/bottom_tv"
/>
</RelativeLayout>
The RelativeLayout tells the layout inflater to draw the first TextView at the top, then draw the second TextView at the bottom, and then fill the rest of the space with your ListView. I believe this is exactly what you want.
Welcome to Android. You'll be using this pattern a LOT!
Change the ListView height to 0dp and add weight=1
i.e.:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Top TextView" />
<ListView
android:id="#+id/listView_Species"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Bottom TextView" />
use android:layout_weight to define weights to your widgets inside the outermost layout. Declare their height as 0dp and then define android:layout_weight to each one of them .
Total weigh sum of the three of them should be 1. According to your need you can deine 0.1 weight to both top and bottom TextView's and define 0.8 to ListView.
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight = "0.1"
android:textSize="30sp"
android:text="Top TextView" />
<ListView
android:id="#+id/listView_Species"
android:layout_width="match_parent"
android:layout_weight = "0.8"
android:layout_height="0dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:textSize="30sp"
android:layout_weight = "0.1"
android:text="Bottom TextView" />

Nearly-wrapping TextView is clipping ImageView in LinearLayout

I have a horizontal LinearLayout set to wrap_content. Inside is a vertical LinearLayout containing a single TextView that allows multiple lines (also wrap_content) and an ImageButton (wrap_content). Several of the components have margins and padding so things space out nicely.
When the text in the TextView is short, everything is fine. When the text wraps to multiple lines, still fine. When the text is almost long enough to wrap, the ImageButton gets clipped horizontally - its left and right sides are lopped off. If I pull out the margins and padding it works, but of course it doesn't look good.
My guess is that the layout system is calculating the text width without taking into account some of the margins and padding. Then it's laying things out, and there's less total space than that first pass at the TextView thought, so it's clipping the second item in the layout and honoring the calculated TextView width. But that is just a guess.
Short of writing my own layout, any ideas?
EDIT
Here's a screen shot from hierarchy viewer, showing where the ImageButton is clipped and with the relevant XML highlighted. The ImageButton's bounds are consistent with what I'm seeing: 27dp wide, whereas the circle image itself is actually 36dp wide, and the ImageButton has 4dp padding specified on each side.
Again, I had to choose that text carefully: any shorter and the button is fine; longer and it would wrap, and the button's fine again.
EDIT
And, here's my XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/messageBubble"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minHeight="#dimen/message_bubble_min_height"
android:layout_alignTop="#id/avatar"
android:layout_alignLeft="#id/avatar"
android:layout_marginTop="#dimen/message_bubble_margin_top"
android:layout_marginLeft="#dimen/message_bubble_inset"
android:layout_marginRight="#dimen/message_inbound_padding_inside"
android:paddingLeft="#dimen/message_bubble_padding_outside"
android:paddingRight="#dimen/message_bubble_padding_inside"
android:paddingTop="#dimen/message_bubble_padding_v"
android:paddingBottom="#dimen/message_bubble_padding_v"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/contentContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="vertical">
<TextView
android:id="#+id/messageBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/message_body_margin_outside"
android:layout_marginRight="#dimen/message_body_margin_inside"
android:layout_marginTop="#dimen/message_body_margin_v"
android:layout_marginBottom="#dimen/message_body_margin_v"
android:gravity="left"
android:autoLink="all"
android:textSize="17dp" />
</LinearLayout>
<include layout="#layout/view_message_action_btn" />
</LinearLayout>
And the included view_message_action_btn:
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:src="#drawable/action_btn"
android:paddingLeft="#dimen/message_action_btn_padding_h"
android:paddingRight="#dimen/message_action_btn_padding_h" />

About LinearLayout and how controls resize

Today I have been playing a bit with the LinearLayout and have been suprised with the results:
<?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="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Big Text"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Button"
/>
</LinearLayout>
This is a simple layout with a text view header, then a text view that I want it to cover all parent (but the space occupied by the bottom button) and a button that is placed at the botton side with the layout_gravity="bottom".
This produces a layout where header is shown correctly, center text view covers all remaining free space and the button does not appear. Why is this? Shouldn't the center text view just calculate its size taking into account the bottom button size?.
Use layout_weight="1" in your center TextView.
Always remember thumb rule
If you are using linear layout with vertical orientation as soon as it finds the control
with
android:layout_height="match_parent"
The layout will ignore all the controls present below it.
Hope this help
Vipul
In place of this
android:layout_width="match_parent"
android:layout_height="match_parent"
use 'wrap_content' like this
android:layout_width="wrap_content"/"fill_parent"
android:layout_height="wrap_content"/"fill_parent"
Shouldn't the center text view just calculate its size taking into account the bottom button size?.
No, because you tell the second TextView to match its parent's height, thus FILL_PARENT and hence it will fill up all remaining space, leaving none for the last TextView.
(...) and a button that is placed at the botton side with the layout_gravity="bottom".
Unfortunately, that's not how a LinearLayout works. If you set the orientation to vertical, basically only the left and right gravities will have effect. Vice versa, with the (default) horizontal orientation, only top and bottom work. The orientation determines in which direction the View children are dynamically positioned in order, which implies you cannot manually change the 'position' in that direction.
Now, to get the desired effect, you can give the second TextView a height of 0dp and a weight of 1, resulting in it dynamically filling up all remaining space without pushing the third TextView off the bottom. Alternatively, you can use a RelativeLayout, with which you can directly set the position, and simply instruct the middle TextView to sit below the first, but above the last.

Categories

Resources