以编程方式创建的 RippleDrawable 看起来与其对应的 xml 不同

问题描述 投票:0回答:2

一段时间以来,我一直在尝试追踪这个问题。我想我前段时间确实找到了解释。不幸的是,它在某处的代码注释中丢失了。

我正在尝试用 Java 创建一个

Material Borderless-Button
。首先,这是按钮在框架中的样子:

按钮背景(button_borderless_material.xml):

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:id="@id/mask"
        android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

用作遮罩的

drawable
btn_default_mtrl_shape.xml):

<?xml version="1.0" encoding="utf-8"?>
<!-- Used as the canonical button shape. -->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:insetLeft="@dimen/button_inset_horizontal_material"
       android:insetTop="@dimen/button_inset_vertical_material"
       android:insetRight="@dimen/button_inset_horizontal_material"
       android:insetBottom="@dimen/button_inset_vertical_material">
    <shape android:shape="rectangle"
           android:tint="?attr/colorButtonNormal">
        <corners android:radius="@dimen/control_corner_material" />
        <solid android:color="@color/white" />
        <padding android:left="@dimen/button_padding_horizontal_material"
                 android:top="@dimen/button_padding_vertical_material"
                 android:right="@dimen/button_padding_horizontal_material"
                 android:bottom="@dimen/button_padding_vertical_material" />
    </shape>
</inset>

Java 等价于

inset-drawable
(btn_default_mtrl_shape.xml):

Drawable createButtonShape(Context context, int color) {
    Resource res = context.getResources();
    int radius = res
            .getDimensionPixelSize(R.dimen.control_corner_material);
    int paddingH = res
            .getDimensionPixelSize(R.dimen.button_padding_horizontal_material);
    int paddingV = res
            .getDimensionPixelSize(R.dimen.button_padding_vertical_material);
    int insetH = context.getResources()
            .getDimensionPixelSize(R.dimen.button_inset_horizontal_material);
    int insetV = res
            .getDimensionPixelSize(R.dimen.button_inset_vertical_material);

    float[] outerRadii = new float[8];
    Arrays.fill(outerRadii, radius);

    RoundRectShape r = new RoundRectShape(outerRadii, null, null);

    ShapeDrawable shapeDrawable = new ShapeDrawable(r);
    shapeDrawable.getPaint().setColor(color);
    shapeDrawable.setPadding(paddingH, paddingV, paddingH, paddingV);

    return new InsetDrawable(shapeDrawable,
            insetH, insetV, insetH, insetV);
}

color
参数是从主题的
attr/colorButtonNormal
获得的 - 在 xml 定义中与
android:tint
使用的颜色相同。

以编程方式创建的

RippleDrawable

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
Drawable createButtonRippleBg(Context context,
                                             int colorButtonNormal,
                                             int colorControlHighlight) {
    return new RippleDrawable(ColorStateList.valueOf(colorControlHighlight),
                    null, createButtonShape(context, colorButtonNormal));
}

我知道即使遮罩颜色/形状没有在视觉上呈现,它的 alpha does 影响

RippleDrawable
。这在这里不是问题 - 用于遮罩的所有颜色都具有成熟的 alpha。

我还确认从属性中读取的颜色 -

colorControlHighlight & colorButtonNormal
- 对游戏中的主题是正确的。

然而,结果是:

Xml 格式:

enter image description here

在Java中:

enter image description here

有趣的是,这发生在 API 21 上。在 API 22 上,两种方法产生相同的结果。

问题:

我确定这是 API 21 上的错误。如果有人能找到它,我们可能可以找到 alpha/颜色值的乘数来抵消这种视觉差异。

除了一般的善意外,我还承诺赏金,因为我已经在这上面花了很多时间。

android button material-design rippledrawable
2个回答
4
投票

试试这个替代构造函数

new RippleDrawable(ColorStateList.valueOf(colorRipple), backgroundDrawable, null);


0
投票

身体{

字体系列:“龙虾”,草书;

背景颜色:#000;

颜色:#fff;

最小高度:100vh;

显示:网格;

放置项目:中心;

}

$duration: 4s;

.旋转{

颜色:海蓝宝石;

位置:相对;滤镜:模糊(2px)对比(4);

字体大小:118px;

}

© www.soinside.com 2019 - 2024. All rights reserved.