Jeff
Jeff

Reputation: 83

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));

Upvotes: 0

Views: 628

Answers (2)

Elhanan Mishraky
Elhanan Mishraky

Reputation: 2816

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

Upvotes: 1

clocksmith
clocksmith

Reputation: 6266

The getWidth() and getHeight() calls in your custom view are causing the rectangle to fill the entire screen. Then, when you add the TextView, it will be drawn off the screen.

If you want the CustomView on the left and the TextView on the right, try adding them like this:

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

By passing an index of 0 in the second addView call, you are telling the LinearLayout to add the view at the front.

Upvotes: 0

Related Questions