views:

1964

answers:

3

How can I size a view based on the size of its parent layout. For example I have a relativelayout that fills the full screen, and I want a child view, say an imageview, to take up the whole height, and 1/2 the width?

I've tried overriding all on onMeasu onLayout onSizeChanged etc and I couldn't get it working....

+1  A: 

When you define a layout and view on XML, you can specify the layout width and height of a view to either be wrap content, or fill parent. Taking up half of the area is a bit harder, but if you had something you wanted on the other half you could do something like the following.

   <LinearLayout android:layout_width="fill_parent"
                android:layout_height="fill_parent">
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
   </LinearLayout>

Giving two things the same weight means that they will stretch to take up the same proportion of the screen. For more info on layouts, see the dev docs.

Mayra
I believe it's `layout_weight`, not `weight`.
Roman Nurik
Also, RelativeLayout ignores layout_weight. Your example would work with a LinearLayout instead.
Romain Guy
I don't recommend this, but...as a hack, if you do use the above approach you could make one of those views a "dummy" and set android:visibility="invisible" to fill half the area
RickNotFred
What is the purpose of only using half the area? Are you planning on displaying anything in the other half? What you do with the remaining area will inform the best approach
RickNotFred
+1  A: 

Roman, if you want to do your layout in Java code (ViewGroup descendant), it is possible. The trick is that you have to implement both onMeasure and onLayout methods. The onMeasure gets called first and you need to "measure" the subview (effectively sizing it to the desired value) there. You need to size it again in the onLayout call. If you fail to do this sequence or fail to call setMeasuredDimension() at the end of your onMeasure code, you won't get results. Why is this designed in such complicated and fragile way is beyond me.

Pavel Lahoda
A: 

You could solve this by creating a custom View and override the onMeasure() method. If you always use "fill_parent" for the layout_width in your xml then the widthMeasureSpec parameter that is passed into the onMeasusre() method should contain the width of the parent.

public class MyCustomView extends TextView {

public MyCustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    this.setMeasuredDimension(
            parentWidth / 2, parentHeight);
}
}   

Your XML would look something like this:

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <view
        class="com.company.MyCustomView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>
Jeff