【问题标题】:StateListDrawable with LayerDrawable created programatically not working on Android 4.0+以编程方式创建的带有 LayerDrawable 的 StateListDrawable 不适用于 Android 4.0+
【发布时间】:2013-04-04 09:24:04
【问题描述】:

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

代码是这样的:

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 设备上,所有方块都是黑色的,并且在选中时不会改变:

问题似乎是在将可绘制对象添加到 StateListDrawable 时... 知道如何解决这个问题吗?

【问题讨论】:

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


    【解决方案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 });
    ...
    

    【讨论】:

      【解决方案2】:

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

      我尝试设置复选框的宽度和高度,一切似乎都正常。 试试这个:box.setWidth(30); box.setHeight(30); 或者,当您使用“new RelativeLayout.LayoutParams(50, 50));”之类的布局参数将复选框添加到布局时。 希望对您有所帮助

      【讨论】:

      • 是的,我使用下面的代码将复选框添加到线性布局,但方块仍然全黑: LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams( context.getResources().getDimensionPixelSize( R. dimen.dashboard_item_size), context .getResources().getDimensionPixelSize(R.dimen.dashboard_item_size));
      猜你喜欢
      • 2013-08-13
      • 2011-09-24
      • 2013-12-05
      • 2015-07-02
      • 2012-02-13
      • 2011-10-06
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多