带有LayerDrawable的StateListDrawable以编程方式创建,无法在Android 4.0+上运行

时间:2013-04-04 09:24:04

标签: android android-custom-view android-drawable android-controls

我正在尝试创建一个带有彩色方块的选项组,供用户选择。它正在使用3.2设备,如下图所示: enter image description here

代码如下:

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

然后,在getColorOption函数中,我创建了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;

SquareShapeDrawable类是一个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);
    }
}

SelectFrameShapeDrawable是:

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

在4.2设备上,所有方块均为黑色,并且在选中时不会更改: enter image description here

问题似乎是在将drawables添加到StateListDrawable时...... 不知道怎么解决这个问题?

2 个答案:

答案 0 :(得分:1)

我通过删除扩展ShapeDrawable的自定义类解决了黑色方块问题,并用直接使用ShapeDrawable类的代码替换它们。此代码似乎适用于所有平台。

虽然原始问题出现在4.2而不是3.2上,但这很奇怪。我最初的灵感来源是: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 });
...

答案 1 :(得分:0)

在我的带有android 4.2修订版2(最新更新)的模拟器中,没有出现复选框,我发现问题是:当setButtonDrawable为null或ColorDrawable时,复选框测量它的大小是0的宽度。这不是StateListDrawable的原因。

我尝试设置宽度和复选框的高度,一切似乎都没问题。 试试这个:box.setWidth(30); box.setHeight(30); 或者当您使用layoutrarams(例如“new RelativeLayout.LayoutParams(50,50))”添加复选框到布局时,“。 希望这个帮助