Вопрос

I am trying to create an option group with coloured squares for the user to choose one. It is working on a 3.2 device and looking like in this picture: enter image description here

The code is something like:

for (int i = 0; i < COLORS.length; i++) {
        CheckBox box = new CheckBox(context);
        box.setBackgroundDrawable(getColorOption(context, COLORS[i]));
        box.setButtonDrawable(android.R.color.transparent);

And then, in the getColorOption function I create the StateListDrawable:

    StateListDrawable slDrawable = new StateListDrawable();

    LayerDrawable checkedDrawable = new LayerDrawable(new Drawable[] {
            new SelectFrameShapeDrawable(transparentColor, lightRedColor),
            new SquareShapeDrawable(color) });
    LayerDrawable uncheckedDrawable = new LayerDrawable(new Drawable[] {
                    new SelectFrameShapeDrawable(transparentColor, transparentColor),
                    new SquareShapeDrawable(color) });
    slDrawable.addState(new int[] { android.R.attr.state_checked },
            checkedDrawable);
    slDrawable.addState(new int[] { -android.R.attr.state_checked }, uncheckedDrawable);
    return slDrawable;

The SquareShapeDrawable class is a ShapeDrawable:

public class SquareShapeDrawable extends ShapeDrawable {
    private final Paint fillpaint;

    public SquareShapeDrawable(int color) {
        super(new RectShape());
        fillpaint = new Paint(this.getPaint());
        fillpaint.setColor(color);
    }

    @Override
    protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
        shape.draw(canvas, fillpaint);
    }
}

And the SelectFrameShapeDrawable is:

private class SelectFrameShapeDrawable extends ShapeDrawable {
private final Paint fillpaint, strokepaint;

public SelectFrameShapeDrawable(int fill, int stroke) {
        super(new RectShape());
        strokepaint = new Paint(this.getPaint());
        strokepaint.setStyle(Paint.Style.STROKE);

        strokepaint.setStrokeWidth((int) (getResources()
                .getDisplayMetrics().density + 0.5f));
        strokepaint.setColor(stroke);
        int padding = (int) (4 * getResources().getDisplayMetrics().density + 0.5f);
        setPadding(padding, padding, padding, padding);

        fillpaint = new Paint(strokepaint);
        fillpaint.setColor(fill);
    }

    @Override
    protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
        if (strokepaint != null)
            shape.draw(canvas, strokepaint);
        shape.draw(canvas, fillpaint);
    }
}

On a 4.2 device all the squares are black and do not change when checked: enter image description here

The problem seems to be when adding the drawables to the StateListDrawable... Any idea how to solve this?

Это было полезно?

Решение

I solved the black squares issue by removing the custom classes that extended ShapeDrawable and replaced them with the code bellow that uses the ShapeDrawable class directly. This code seems to work on all platforms.

It is weird though that the original issue was present on 4.2 and not on 3.2. My original source of inspiration was this: http://www.betaful.com/2012/01/programmatic-shapes-in-android/

    ShapeDrawable selectFrame = new ShapeDrawable();
    selectFrame.setShape(new RectShape());
    selectFrame.getPaint().setColor(lightRedColor);
    selectFrame.getPaint().setStyle(Paint.Style.STROKE);
    selectFrame.getPaint().setStrokeWidth((int) (getResources().getDisplayMetrics().density + 0.5f));
    int padding = (int) (4 * getResources().getDisplayMetrics().density + 0.5f);
    selectFrame.setPadding(padding, padding, padding, padding);

    ShapeDrawable square = new ShapeDrawable();
    square.setShape(new RectShape());
    square.getPaint().setColor(color);

    LayerDrawable checkedDrawable = new LayerDrawable(new Drawable[] {
            selectFrame, square });
...

Другие советы

In my simulator with android 4.2 revision 2 (the lastest update), the checkbox does not appear, and I found the problem is: when setButtonDrawable as null or ColorDrawable, the checkbox measure it's size is 0 of width. This is not cause of the StateListDrawable.

I try to set width, and height of checkbox, and everything seems OK. Try this: box.setWidth(30); box.setHeight(30); Or when you add the checkbox to the layout using the layoutparams like"new RelativeLayout.LayoutParams(50, 50));". Hope this help

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top