I have a table layout with 5rows. I'd like the size of first row to take the rest of the screen while the remaining rows take as much space they need based on the content inside.
My first intuition was to make the first row's layout width and height set to match_parent while having the other rows' width to match_parent and height to wrap_content. Needless to say, this does not work.
How can I accomplish this?
I'd like the size of first row to take the rest of the screen while
the remaining rows take as much space they need based on the content
inside.
I think that using android:layout_weight="1" on the first TableRow should solve the problem you have.
Put your TableLayout inside a ScrollView and fix the Height of your First TableRow which will solve your issue. Hope it works.
Seeing as TableLayout inherits from LinearLayout, have you tried setting Row height to 0dp and setting layout weights for each one to achieve the desired effect? Like so:
<TableRow
android:layout_height="0dp"
android:layout_weight="2"
android:layout_width="match_parent">
<TableRow
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent">
and so on....
stick to your first intuition but add layout_weight="1" to the first row.`
Related
This is what is causing me many problems:
<RelativeLayout
android:id="#+id/galleryLayout"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#color/white">
<android.support.v4.view.ViewPager
android:id="#+id/imageViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/circlePageIndicator"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="#dimen/padding_middle"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Right now this code kind of works only because I've set RelativeLayout's height to 180dp but I don't want to have it this way. I want the whole thing to have height according to ViewPager's child.
There are exactly 2 problems if I set RelativeLayout's height to WrapContent.
Problem 1
ViewPager will expand throughout the whole screen. It just doesn't respect it's wrap_content height attribute. But I've partially solved that with this answer. I'd still appreciate if there's a better solution though.
Problem 2
I want have CirclePageIndicator on the bottom of it's parent (RelativeLayout) so I've added attribute layout_alignParentBottom="true" but now because of this, the RelativeLayout will expand throughout the whole screen for some reason.
So what I'm trying to have is a RelativeLayout which wraps around ViewPager which wraps around it's child. The child is downloaded from web so I can't pre-set it. And on the bottom of that RelativeLayout, I want to have a ViewPagerIndicator.
As for the problem 1 you solved the issue correctly, ViewPager will not wrap its children by default.
As for the second problem, this is a normal RelativeLayout behaviour. If you set its height to wrap_content and add two children, one with layout_alignParentTop="true" and second one with layout_alignParentBottom="true", they will stretch your layout height-wise.
What you should do is: ask yourself if you really need RelativeLayout. If you've provided the whole layout of yours I don't see a need for RelativeLayout (its costly). Vertical LinearLayout would do just fine. If you decide that you really need RelativeLayout, try changing your Indicator's rule from layout_alignParentBottom="true" to android:layout_below="#+id/imageViewPager".
I have this layout file from Chapter 13 of Android Programming: The Big Nerd Ranch Guide:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="#drawable/armstrong_on_moon"
android:contentDescription="#string/hellomoon_description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:layout_weight="1"/>
<TableRow
android:gravity="center|bottom"
android:layout_weight="0">
<Button
android:id="#+id/hellomoon_playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hellomoon_play"/>
<Button
android:id="#+id/hellomoon_stopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hellomoon_stop"/>
</TableRow>
</TableLayout>
And it results in a layout that looks like this. What I do not understand is how the TableRow shows up in the layout at all since its layout_weight is 0 and the ImageView's layout_weight is 1. My understanding is that the way layout_weight works is it will first respect the layout_width and layout_height of each element, and then divide up the remaning space between the elements based on layout_weight. But since the ImageView has match_parent for both its layout_width and layout_height, shouldn't it take up the whole screen and then leave nothing left to divide with the TableRow? I believe that the TableRow also has match_parent for both its layout_width and layout_height attributes since it inherited them from TableLayout, but since it came second I thought the ImageView would dominate the screen. Also, even if the the ImageView shouldn't take up the whole screen, aren't the layout_weights saying that the ImageView should get 100% of the remaining space and the TableRow should get 0%? Additionally, when I increase the layout_weight of the TableRow, the TableRow just gets pushed further and further off the screen as it increases more-- but I thought that this should increase the space the TableRow takes up on the screen. Can anyone explain what I'm misunderstanding here.
In case it helps, my understanding for layout_weight comes from this example in the book:
**How android:layout_weight works**
...
LinearLayout makes two passes to set the width of a view. In the first pass, LinearLayout looks at layout_width (or layout_height, for vertical orientation). The value for layout_width for both the Button and CheckBox is now wrap_content, so each view will get only enough space to draw itself (Figure 8.12).
...
In the next pass, LinearLayout allocates any extra space based on the values for layout_weight.
The TableRow has a height of wrap_content. This is enforced by the TableLayout, as per the documentation:
The children of a TableLayout cannot specify the layout_width attribute. Width is always MATCH_PARENT. However, the layout_height attribute can be defined by a child; default value is WRAP_CONTENT. If the child is a TableRow, then the height is always WRAP_CONTENT.
TableLayout and TableRow are both LinearLayout subclasses, but I experienced the same strange behaviors when I created a layout like the one in your post. Browsing the source of TableLayout and TableRow, it's not immediately clear to me what causes this (clearly there's some overridden logic in the measuring code, but that's not really satisfactory to figure out things like column spans and to adjust column widths and such, but I'd have to dig more to figure out what's going on).
Unless this example actually needs/uses some of the special behaviors of TableLayout and TableRow, I would advise just using LinearLayouts instead for the sake of clarity. The presence of layout_weight with those two views is frankly confusing and clearly doesn't behave as expected. In either case, you don't even need the layout_weight="0", whether you use twoLinearLayout`s or keep the example as-is.
I'm doing a menu. The problem is that my buttons are too close to one another. I would like to separate them a bit.
Also I would like to extend them (rozszerzyć je) to the similar sizes.
Here you have the code:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button2"
android:layout_centerHorizontal="true"
Here you have the image of this problem:
And each button out of the 4 ones has a similar code. (the difference is in layout_above.
How to make it?
Thanks in advance!
Any reason why you have to use a RelativeLayout? If you can use a LinearLayout I'd use something like:
<LinearLayout
android:layout_width="..."
android:layout_height="..."
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding_top="4dp"
android:padding_bottom="4dp"
... />
</LinearLayout>
This would get all your buttons to be the same size horizontal and vertical. You can tweak the padding top and bottom to get the desired effect.
The way layout_weight works is it takes the leftover space of the parent view, and portions them out to the children views according to their weights. Since the height of every button is 0dp, 100% of the vertical space is left to partition out. Since the weight of all the buttons is the same, they will be roughly the same size.
This explanation is for a vertical LinearLayout. For a horizontal, just switch the values of layout_height and layout_width.
I would like to place a layout on the bottom of a LinearLayout, but I can't seem to get it to work. I know that I can use RelativeLayout to do this, but I should be able to use LinearLayout, shouldn't I?
EDIT: Actually this is more confusing than I thought. The layout below is simplified. In reality, I'm using fragments on a pre-3.0 device, with the compatibility layer.
I used Hierarchy Viewer to examine what's going on, and found that an android.support.v4.app.NoSaveStateFrameLayout was added to my layout, and that layout has layout_height set to wrap_content. That seems to be what's causing my problem, but I haven't yet figured out how to fix it.
Specifically, why doesn't this work? Shouldn't the layout_gravity place it at the bottom?
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
... stuff here ...
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal">
... more stuff here ...
</LinearLayout>
</LinearLayout>
BTW, changing layout_height to fill_parent or setting layout_weight don't seem to work either. I just want to better understand what is going on, because clearly I'm missing something important. Thanks.
First of all nice question.
Android behaves we can say weird in the situation like this.
if you have selected your parent linear layout's orientation horizontal then you can set its child component at bottom by setting its layoug_gravity=bottom. suppose you have added 2 text views in that horizontal linear layout and second textview's layout_gravity is bottom then it will set to bottom but it work like it is set at bottom in other column then the first text view. NOTE : you can set textview's layout_gravity = "left" or "right" when its parent linearlayout is horizontal but you cant see its result.
Oppositely, if you have selected parent linearlayout's orientation vertical then you can set its child component at left or right by using layout_gravity. but the second textview will shown in you can say next row with left or right gravity as you have set. NOTE you can set textview's layout_gravity = "top" or "bottom" when its linear layout is vertical but you can not see its result.
Try to make sample xml design as i have stated above so you get better idea.
Strange but True!!! Try to understand this behavior. :)
Just add space between what you want at the bottom and all the rest:
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
So I resolved the problem. It's a two-part solution:
First, the way to do this without using LinearLayout is to provide weight to the element above so that it takes up all of the empty space. BTW, you can see this example in the API demos: http://developer.android.com/resources/samples/ApiDemos/res/layout/linear_layout_3.html
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
... stuff here ...
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weight="1"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
... more stuff here ...
</LinearLayout>
</LinearLayout>
This by itself didn't solve my problem, as I had a NoSaveStateFrameLayout with layout_width="wrap_content" as a parent view, and so I needed to get that fixed first. I'm using code based on the wonderful Google I/O App, and when I searched the code for NoSaveStateFrameLayout, I found this:
// For some reason, if we omit this, NoSaveStateFrameLayout thinks we are
// FILL_PARENT / WRAP_CONTENT, making the progress bar stick to the top of the activity.
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
Thanks for an awesome comment Google!!! I added this into my source and everything worked great!
The moral of the story: Hierarchy Viewer and comments are your friends.
LinearLayout will just stack things as they are placed in there. Since it is vertical, it will keep placing items one after the next in a vertical manner. Can you change the android:gravity of the linearLayout and not the layout_gravity of the nested one and see if that works.
RelativeLayout of course should be the first way but you stated you didnt want to do that. Is there reason for that?
It could be that, as per https://stackoverflow.com/a/13366783/513038, you need to set the parent LinearLayout to have android:baselineAligned="false". Worked in my case.
I was wondering if it's possible to set an automatic/dynamic margin (padding?) between elements in an Android layout without having to do it programmatically?
For example let's say there is a horizontal LinearLayout which is set to android:layout_width="fill_parent" and that contains five elements. Is there a setting that evenly shares the remaining empty space of the LinearLayout to the margins of the child elements?
See image at http://img63.imageshack.us/img63/8/margin.png
Thanks for any help!
You could use view spacers as your margin, with the layout weight set on them.
<LinearLayout ...>
<View id=marginLeft android:layout_weight="1"/>
<Element1/>
<Element2/>
<Element3/>
<Element4/>
<Element5/>
<View id=marginRight android:layout_weight="1"/>
</LinearLayout>
This should make the two views use up any remaining space in your row. Note, the above XML will not parse :)
-- Edit
Just saw the picture. To add equal spacing between each of the elements too would just be a case of adding more spacer elements between your content elements (all with the same layout weight)
Yup. Only LinearLayouts support it. Tis called layout weight
Look for LinearLayout at http://developer.android.com/guide/topics/ui/layout-objects.html
For a good intro, look here