0

I have a LinearLayout which I would like to set a background programmatically. This background should be very simple, just two rectangles one next to each other. The width of the rectangles is only known at runtime. What would be the best way?

    ShapeDrawable done = new ShapeDrawable(new RectShape());
    done.setBounds(new Rect(0, 0, 0, 0));
    done.getPaint().setColor(Color.GREEN);

    ShapeDrawable remaining = new ShapeDrawable(new RectShape());
    remaining.setBounds(new Rect(20, 0, 0, 0));
    remaining.getPaint().setColor(Color.RED);

    LayerDrawable composite = new LayerDrawable(new Drawable[]{remaining, done});
    weightRow.setBackgroundDrawable(composite); 

I have tried to create a compound drawable like this, where I've expected the remaining rectangle to start at position 20, but it just fills the whole layout.

1
  • I haven't worked with LayerDrawable much/in a while, but from what I remember, drawable containers like LayerDrawable may maintain or consolidate state among all the drawables in that container (like bounds). Commented May 21, 2013 at 7:04

2 Answers 2

1

I'll answer my own question. After reading more posts I've realized, that simulating the android:top, left, ... from xml drawable, you should use the setLayerInset(int index, int l, int t, int r, int b) of the LayerDrawable on the layer you want to shift.

ShapeDrawable done = new ShapeDrawable();
done.getPaint().setColor(Color.GREEN);

ShapeDrawable remaining = new ShapeDrawable(new RectShape());
remaining.getPaint().setColor(Color.RED);

LayerDrawable composite = new LayerDrawable(new Drawable[]{done, remaining});
composite.setLayerInset(1, 0, 0, 100, 0);

layout.setBackgroundDrawable(composite);
Sign up to request clarification or add additional context in comments.

Comments

0

You can make a custom class that extends ShapeDrawable. Implement the onDraw() method to define how it should draw itself; you cant programmatically draw your rectangular regions using the Canvas and Paint APIs. You can then define a method to set the widths of those regions at runtime.

In your Activity, make a new instance of this class and call setBackgroundDrawable() on the LinearLayout.

3 Comments

Hi, thanks for the answer, I've already tried that, but the trouble is that it scales the border between the rectangles so it looks blurry and i want a nice sharp edge.
Wouldn't that have to do with your drawing code? I can't think of a better way to accomplish what you want, unless you just put two Views inside a LinearLayout and change their layout weights at runtime (which is much more expensive as it requires an entire traversal of the view hierarchy to re-measure and layout the views before the redraw, whereas my suggestion only involves the redraw)
Its a scaling issue i believe, the border between the rectangles is lets say antialiased.. Anyway.. I have the screen width, so the scaling on x-axis won't happen.. So I'll make it that way. But i would still like to see comment on my question. Shouldn't it work ? I believe it should.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.