【问题标题】:Changing button shape background color更改按钮形状背景颜色
【发布时间】:2014-07-02 08:13:52
【问题描述】:

我尝试创建某种自定义圆形按钮,例如this answer。 但是我的 GridView 需要很多(大约 18 个),并且它们都应该有不同的背景颜色。

不幸的是,view.setBackgroundColor(int c) 不仅改变了我的自定义按钮的颜色,而且改变了形状(所以我的圆角消失了。

那么,有没有办法只改变视图的背景颜色(形状的颜色)而不改变它的形状? (创建 18 个不同的 xml 并不是最好的方法)

适配器的完整代码:

PaletteView view = (PaletteView) ((convertView == null) ? mInflater.inflate(R.layout.palette_item, null)
            : convertView);

    view.findViewById(R.id.rounded).setBackgroundColor(mColors[position]);

    return view;

【问题讨论】:

  • 请查看thisthis 可能会对您有所帮助
  • @RDC 您提供了有关如何创建圆形按钮的链接。如您所见,我遇到了一些不同的问题。
  • 第二个链接也包含背景颜色的信息,这就是我与你分享的原因。
  • @RDC 是的,但它是硬编码的并且与特定的形状相关联。如果我在我的情况下这样做 - 我需要创建 18 个不同颜色的相似形状。我不认为这是合理的

标签: android button view colors background


【解决方案1】:

没有时间测试,但也许......

为你想在你的drawable中改变颜色的项目添加一个ID(shape_id)。 然后使用以下

 LayerDrawable bgDrawable = (LayerDrawable) view.getBackground();
 GradientDrawable shape = (GradientDrawable) bgDrawable.findDrawableByLayerId(R.id.shape_id);
 shape.setColor(mColors[position]);

https://stackoverflow.com/a/16637696/3309883

【讨论】:

  • 不,此代码引发类转换异常: android.graphics.drawable.StateListDrawable 无法转换为 android.graphics.drawable.LayerDrawable 我认为这是因为我正在使用选择器(重点关注 2 个状态项并且没有重点)用于我的自定义按钮。
【解决方案2】:

所以,我找到了解决它的方法 - 以编程方式创建形状/选择器。

现在,我只得到了带有形状的 rounded_shape.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >

<corners android:radius="@dimen/rounded_radius" />

<stroke android:width="1dip" />

并创建了用于为按钮创建完整选择器的静态类:

public class DrawableUtils {

/**
 * Blend {@code color1} and {@code color2} using the given ratio.
 * 
 * @param ratio
 *            of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend, 0.0 will return
 *            {@code color2}.
 */
private static int blendColors(int color1, int color2, float ratio) {
    final float inverseRation = 1f - ratio;
    float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
    float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
    float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
    return Color.rgb((int) r, (int) g, (int) b);
}

/**
 * Create selector with specified {@code mainColor} (setting darkened {@code mainColor} for state_pressed)
 * 
 * @param mainColor
 *            color of the view
 */
public static StateListDrawable getSelector(Context c, int mainColor) {
    StateListDrawable selector = new StateListDrawable();
    /*
     * CAREFUL! We NEED to use 2 different objects instead of using 1 with different setColor(...) calls
     */
    GradientDrawable stateSimple, statePressed;

    // Getting pre-created shape
    statePressed = (GradientDrawable) c.getResources().getDrawable(R.drawable.rounded_shape);
    stateSimple = (GradientDrawable) c.getResources().getDrawable(R.drawable.rounded_shape);

    // Setting color for state_pressed
    statePressed.setColor(blendColors(mainColor, c.getResources().getColor(R.color.tinted_black), 0.5f));
    selector.addState(new int[] { android.R.attr.state_pressed }, statePressed);
    selector.addState(new int[] { -android.R.attr.state_enabled }, statePressed);   // "-" is for "false"

    // Setting color for main state
    stateSimple.setColor(mainColor);
    selector.addState(new int[] { android.R.attr.state_enabled }, stateSimple);

    return selector;
}

}

最后,从 GridView 适配器调用它:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        view.findViewById(R.id.rounded).setBackgroundDrawable(DrawableUtils.getSelector(mC, mColors[position]));
    } else {
        view.findViewById(R.id.rounded).setBackground(DrawableUtils.getSelector(mC, mColors[position]));
    }

【讨论】:

    猜你喜欢
    • 2015-06-04
    • 1970-01-01
    • 2014-11-05
    • 2021-06-22
    • 2015-04-03
    • 1970-01-01
    相关资源
    最近更新 更多