Making a View occupy a fixed width in Android layout - android

I have this as part of my layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:layout_weight="0.15">
<TextView
android:id="#+id/question_text"
android:layout_width="0dip"
android:layout_height="fill_parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/score_label" />
<TextView
android:id="#+id/score_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right" />
</LinearLayout>
The first TextView is empty at the beginning of the application. Its content is changed dynamically. This makes it occupy zero space so that the second TextView is aligned to the left, even though its layout_gravity is set to right.
How can I make it occupy a fixed width, without taking the contents into account?
I thought about using layout_weight, but I know the recommendation is against using nested weights (the parent ViewGroup has a layout_weight attribute). Maybe I should use a RelativeLayout?
Thanks for any suggestions.

I solved a similar problem using the attribute android:ems="<some number>" on the TextView. An "ems" is the width of the character "M". This attribute makes the TextView exactly the given no. of ems wide.
http://developer.android.com/reference/android/widget/TextView.html

You have all of your TextViews width set to android:layout_width="wrap_content" which means that if there's nothing in there it will have no width. You need to set that to either "match_parent" which will make it the same width as it's parent container or set it to a fixed value, something like android:layout_width="100dp".

Related

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

Android: Bottom nav bar with equally space buttons

Hi I'm trying to create a bottom nav bar for my application similiar to the iphone zappos app:
I currently have a linear layout within my relative layout. The code is here:
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="60dip"
android:orientation="horizontal">
<Button
android:layout_height="fill_parent"
android:id="#+id/navhomebtn"
android:text="Home"
android:layout_width="wrap_content" />
<Button
android:layout_height="fill_parent"
android:id="#+id/navsearchbtn"
android:text="Search"
android:layout_width="wrap_content" />
<Button
android:layout_height="fill_parent"
android:id="#+id/navfavbtn"
android:text="Favorites"
android:layout_width="wrap_content" />
<Button
android:layout_height="fill_parent"
android:id="#+id/navloanbtn"
android:text="Loans"
android:layout_width="wrap_content" />
</LinearLayout>
When I change the buttons to fill parent they just overlap each other and don't respect the others size. I was hoping to get them to fill the space so different size phones will all have a similar UI experience. Otherwise I would have to set them as fixed width and have it centered with a background that blends (which I don't want to do).
Please help!
Use layout_weight of 1 in your LinearLayout and use 0dp for layout_width and 0.25 for layout_weight in your buttons.
Use layout_weight on the buttons. Set all button's layout_weight to 1 and each will take 1/n of its parent's width.
Try passing 0dip for each layout_width.
As the other guys mentioned, the easiest way is to set the layout_width to 0dip and set the layout_weight. An alternate approach would be to use a RelativeLayout instead, and manually set the layout_alignParentLeft/Right and layout_toLeft/Rightof.

RelativeLayout is taking fullscreen for wrap_content

Why does FOOBARZ get layed out all the way at the bottom when no elements are layout_height="fill_parent" in other words, all elements are wrap_content for height?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/feed_u"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_marginLeft="5dip"
android:scaleType="centerCrop"
android:drawableTop="#android:drawable/presence_online"
android:text="U" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/feed_u">
<ImageView
android:id="#+id/feed_h"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/btn_minus" />
<ImageView
android:id="#+id/feed_ha"
android:layout_toLeftOf="#id/feed_h"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/btn_plus" />
<TextView
android:id="#+id/feed_t"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title">
</TextView>
<TextView
android:id="#+id/feed_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Band"
android:layout_below="#id/feed_t">
</TextView>
<TextView
android:id="#+id/feed_s"
android:layout_below="#id/feed_a"
android:text="S"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
<TextView
android:id="#+id/feed_tm"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="FOOBARZ"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
</RelativeLayout>
</RelativeLayout>
From the RelativeLayout doc:
Class Overview
A Layout where the positions of the children can be described in relation to each other or to the parent.
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM
Class documentation
Which is exactly your case. RelativeLayout can not do that.
For those looking for a solution to this, like I did, you can use FrameLayout instead of RelativeLayout.
Then you can set the gravity the intended object to bottom right as below
<TextView
android:layout_gravity="bottom|right"
android:text="FOOBARZ"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
You have set the RelativeLayout to "wrap_content"
and the TextView to android:layout_alignParentBottom="true", so it automatically tries to stretch the RelativeLayout to the bottom. Don't use such dependencies with Relative Layout, as it can count as "circular dependencies".
From the docs for RelativeLayout:
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a
RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.
Try to align your TextView to something other than the parent RelativeLayout, but watch out for this problem as well:
Circular dependencies, need some help with exact code
Alternatively, try to add more sophisticated inner layouts.
Dont use alight_Parent type properties with the child views
You can use frame layout instead of RelativeLayout with respective gravity
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<TextView
android:layout_gravity="bottom|right"
android:text="Hello "
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
</FrameLayout>
FrameLayout is usually good for placing different views one on top of each other (where the most recent child is on top of the previous child). In your case, you'd like to place views one next to each other (above, below, start, end), so I think ConstrainLayout fits better because it's exactly what it does.
Unlike RelativeLayout, you'd be able to set the ConstrainLayout width to wrap_content and still arrange its children views as you wish, for example instead of
android:layout_alignParentTop="true"
you can use
grid:layout_constraintTop_toTopOf="parent"
and instead of
android:layout_alignParentBottom="true"
you can use
grid:layout_constraintBottom_toBottomOf="parent"
Good answers. Now if you don't have layout_alignParentBottom="true" and still getting this issue watch out for android:background="#drawable/bkgnd" where bkgnd is a biggie.
I'm not sure why the clean and obvious way of accomplishing this hasn't been posted yet. This performant solution works for any View MyView with a known height.
Wrap your RelativeLayout with height wrap_content in a FrameLayout:
<!-- width here should constrain RelativeLayout -->
<FrameLayout
android:layout_width="#dimen/my_layout_width"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<MyView
...
android:layout_gravity="bottom" />
</FrameLayout>
Just note that the view at the bottom of the FrameLayout will be on top of your RelativeLayout content, so you'll need to add padding to the bottom of that layout to accomodate it. If you want that view to be variable height, you can either Subclass FrameLayout to add padding in code based on the measured view height, or just change the FrameLayout to vertical LinearLayout if you're not worried about the performance, i.e. it's not a listview item, or the views are relatively lightweight.
Not sure why all the answers here suggest FrameLayout, which is designed to render a single view or views layered in the z axis. OP's problem is a sequence of views stacked vertically, which should be in a LinearLayout.

Android layout weight problem

friends,
i have written following layout code and buttons to be displayed on screen equally but it not seems to work any one guide me what mistake am i doing?
![<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#color/color_panel_background"
>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/currentLocation"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/current_location_icon"
/>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/searchCity"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/search_icon"
/>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/home"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/home_icon"
/>
</LinearLayout>
</RelativeLayout>][2]
The drawable for the middle button is obviously bigger than the other two. You set the height of the buttons with wrap_content, so the middle button gets bigger. Weight has nothing to do with this. Its only defining how much space the item takes when you use fill_parent.
Easiest way to fix this is either changing the layout_height to a fixed value (use dp as unit)
or change the size of your drawables making the images all the same size to begin with.
Thumbs up for the way you asked the question. Screenshot and relevant code. Wish everybody would do that :)
Change android:layout_height from "wrap_content" to some constant if you want them to have equal height.
change your linear layout height to some constant and
change object layout_height within the linear layout to fill_parent
in Horizontal: if you set weight for child view then set with = 0dp
in Vertical: if you set weight for child view then set height = 0dp

Categories

Resources