Search code examples
android-linearlayoutandroid-viewandroidandroid-custom-view

Overflow of Android LinearLayout / Missing Components?


I'm having trouble with what seems to be a very basic Android layout issue. I've simplified this to the sample below. I have two views:

  1. a custom view (MyCustomView) which just draws a blue rectangle with a red border and
  2. a TextView that says "Sample Text"

I add these to a linear layout that I'm creating through code (not XML). If I add the TextView first, I get the following which makes sense to me:

enter image description here

If however I swap the order of the two layout.addView(...) calls, the TextView is missing:

enter image description here

In the first case, the TextView expands to it's preferred width and then MyCustomView takes the rest. I'd like the second case to behave similarly - I again want the TextView to be as wide as its ideal width (IE just fitting the text) and want the custom view to take up the rest of the width. I specifically do not want to use absolute sizing - instead I want the custom component to just take up the residual.

In Swing this is typically done with preferredSize but that doesn't seem to exist in Android. What am I missing? Thanks.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LinearLayout layout = new LinearLayout(this);

    MyCustomView myCustomView = new MyCustomView(this);

    TextView textView = new TextView(this);
    textView.setText("Sample Text");

    layout.addView(myCustomView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    layout.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));

    setContentView(layout);
}

public class MyCustomView extends View {

    private Paint paint = new Paint();

    public MyCustomView(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // fill blue box
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0, 0, getWidth(), getHeight(), paint);

        // draw red border
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);
        canvas.drawRect(0, 0, getWidth(), getHeight(), paint);

    }
}

EDIT Nov 18 5:52PM EST as per @Elhanan, I've changed the two addView(...) lines to be:

layout.addView(myCustomView, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1));
layout.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0));

Solution

  • You need to set the layout_width of your custom view to 0 and it's layout_weight to 1 when adding it.