views:

320

answers:

2

Hi stackies,

I really tried to, but I can't understand how Android interprets layout_weight setting...

What I'm trying to archieve is

  • a header on top with a fixed height
  • an input area at the bottom containing an EditText and a Button
  • a content part in the middle that's taking all what's left of space

When typing I'd like to grow the EditText to a specific height and to start scrolling if the text entered exceeds the available height. Doing this I need the surrounding LinearLayout to grow together with the EditText.

If I define a specific height for the inner LinearLayout it won't grow. If I don't, the inner layout takes ALL the space instead of the ScrollView, no matter what I try using layout_weight. :(

My current XML looks like that:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="I'm a header" />
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="bottom">
        <LinearLayout
            android:id="@+id/itemContainer"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </ScrollView>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:padding="2dp"
        android:gravity="bottom"
        android:isScrollContainer="true"
        android:background="@drawable/steel" >
        <EditText
            android:id="@+id/edittext01"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.2"
            android:scrollbars="vertical"
            android:fadingEdge="vertical"
            android:fadingEdgeLength="60dp"
            android:maxHeight="40dp"
            android:textSize="15sp" />
        <Button
            android:id="@+id/button"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.8"
            android:layout_gravity="right"
            android:text="Send"
            android:textStyle="bold"
            android:textSize="15sp" />
    </LinearLayout>
</LinearLayout>

Any tips are greatly appreciated!

Best regards
S.

+1  A: 

I believe you would be better off with a RelativeLayout. Add your header, and set it to layout_alignParentTop="true". Then add your EditText and Button, set that area to layout_alignParentBottom="true". Then, add the center area, set the width and height to fill_parent, and set layout_above="{the id of the EditText/Button layout}", and layout_below="{the id of the header layout}".

I don't have Eclipse at work, otherwise I would test it for you, but that should work.

kcoppock
Thanks alot, kcoppock! I'll test that within an hour or two and let you know whether it works.
Sotapanna
Hm, it didn't really change anything. Only the header disappeared. ;)If I use LinearLayout again the header comes back. I kept 'layout_alignParentTop="true"' and 'layout_alignParentBottom="true"' as you suggested. As soon as I set the inner 'LinearLayout' to 'layout_height="wrap_content"' it fills half the screen.Additionally, I don't understand why the EditText takes 80% of the width within the LinearLayout as it is defined to have 'layout_weight="0.2"'. But that's not the question here... ;)
Sotapanna
Could you post what you tried onto a pastebin.com link? Or just edit it into the original post? I can take a look at it and see if anything jumps out. Oh, also, the layout weight should be just integers I believe. If I recall correctly, all the layout_weights defined should add up to 10. So a weight of 2 is 20%. I could be wrong on that though.
kcoppock
http://pastebin.com/DS2Mje9G
Sotapanna
http://pastebin.com/5SLveXFe Try that one. It did some weird things with my XML comments, but there's basically four lines of code I added.
kcoppock
I tried that. All I had to edit to make Eclipse compile was to place the footer before the ScrollView so it could be found. Now the header is there, but the footer still takes 50% of the screen, aligning the button and EditText to it's top. I have the feeling the structure in a whole is right, but the inner LinearLayout not.Thanks so much for your help so far! :)
Sotapanna
No problem! :) Hmm, give this one a try: http://pastebin.com/6tm20anP I substituted a RelativeLayout for the footer, and made a few other changes (what was the isScrollContainer attribute for?). I believe this should work.
kcoppock
Nope. :( Still the footer takes that much space. kcoppock, thanks a lot! I guess I will try Mayra's approach. Ow, and isScrollContainer defines that "the view will serve as a scrolling container, meaning that it can be resized to shrink its overall window so that there will be space for an input method." Well, at least it was worth a try! :)
Sotapanna
That is strange. :( Well, I'll give it a go when I get home, it's probably something simple I missed. And good to know about the scroll container thing, that's new to me.
kcoppock
Cool, thanks! And as soon as I found out how to use the scroll container thingy I'll let YOU know! ;)
Sotapanna
kcoppock, it was the background image! it seemed to have forced the widget to keep it's size! damnit...
Sotapanna
+1  A: 

layout_weight is used to determine how Android divides up any left over space after the various widgets get all of the space they want.

So say you have 3 widgets in a row, each of which want 10 pixels, but you have 50 pixels worth of space. Here are a few examples of layout_weights and the number of pixels each widget will claim:

widget1: weight = 1, 30px
widget2: weight = 0, 10px
widget3: weight = 0, 10px

widget1: weight = 1, 20px
widget2: weight = 1, 20px
widget3: weight = 0, 10px

widget1: weight = 1, 16.5px
widget2: weight = 1, 16.5px
widget3: weight = 1, 16.5px

You can think of the weight as a percentage of available space. It will add up all of the values, and then give out portions as appropriate. Thus, if it helps you can use weights that add up to 100 to do percentages:

widget1: weight = 0, 10px
widget2: weight = 25, 15px
widget3: weight = 75, 25px

If I understand correctly, you want the bottom widget to start at a particular size, then expand to some maximum size if necessary, and then scroll.

And, you want the widget above it to take over all of the extra space.

Unfortunately in Android its not realy possible to specify a maximum size. I think the best you could do would be to give the ScrollView some fixed size, with a layout_weight = 1 and tell the bottom LinearLayout to wrap_content. This would (I think) cause the LinearLayout to expand until it can't anymore, because the ScrollView has already claimed the space.

However, the challange is specifying a fixed size for the ScrollView that makes sense at all different screen sizes and resolutions. You might end up having to create different layouts for the different resolutions, which is probably not worth it. Personally, I'd just give the editText a fixed size...

Mayra
Thanks Mayra. That's exactly what I try to do. Maybe kcoppock has an other idea. If it has to be I'll end up creating layouts for different solutions. :( Setting ScrollView to a specific size AND adding layout_weight = 1 would cause the ScrollView to take all the space it can get and to "shrink" to it's defined size as soon as some other widget takes more space, right?
Sotapanna
Yup, thats the idea.
Mayra
Sounds right. I believe there's a setMultiLine attribute for EditTexts. If you set that, and set the height to wrap_content, I'm fairly sure it will expand to fit, and shrink the ScrollView accordingly.
kcoppock
Hey Mayra! I tried various versions of setting a ScrollView, a LinearLayout etc. to a specific size and layout_weight=1, but the growing EditText is even growing out of the screen if I keep typing! You think I'm completely on a wrong track?! Wouldn't have expected to spend hours on that... ;)
Sotapanna
By growing out of the screen, you mean it doesn't scroll? Just goes off screen? That sounds odd.. as I said though, personally I would just set the edit text to a particular size to start, and then scroll it, and not try to have it expand. I've never seen anything like what you describe before, so it might just not be possible without specialized code changes. Sorry!
Mayra
Right! The EditText never scrolls! :) It just grows and grows. I don't modify the XML programmatically. It's still just the way you can see it above, just without the background image.
Sotapanna
Does it scroll if you set a specific size on the EditText?
Mayra
I'll check that this evening!
Sotapanna
Mayra, if I set layout_height to a specific height it scrolls, and setting scrollbars="vertical" then shows the scrollbar. I guess I'll calculate a nice height for the EditText using the DisplayMetrics. Thanks for your help!
Sotapanna