【问题标题】:Change the shape color of a ImageButton更改 ImageButton 的形状颜色
【发布时间】:2016-02-14 22:14:30
【问题描述】:

我有一个 recyclerView,我在其中创建了 12 个 ImageButton。 默认情况下,它们都是黑色的,因为我为具有黑色纯色的 imageButton 制作了自定义形状。自定义形状设置为 imageButtons 背景

形状:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners
    android:radius="5.3dp"/>
<solid
    android:color="#000000"/>


</shape>

这就是 ImageButtons 现在的样子。但是它们都有相同的颜色,这不是我想要的。

我想动态地为每个 ImageButton 赋予与我的 color.xml 中的颜色数组不同的颜色。我已经尝试了许多关于如何更改形状的纯色的解决方案,但都没有奏效。

为recyclerView创建12个imageButton的方法:

 public static List<ColorButton> initColorButtons(){

    colorButtonList = new ArrayList<>();

    //here we retrive all colors from color.xml
    Resources resources = App.getAppContext().getResources();
    String colors[] = resources.getStringArray(R.array.backgroundcolors);

        for(int i=0; i<colors.length; i++){

        //Creates 12 ImageButtons with a custom shape
        colorButtonList.add(new ColorButton(new ImageButton(App.getAppContext()), colors[i]));


        //Here each imagebutton should get its own color.
        Drawable drawable = colorButtonList.get(i).getButton().getBackground();

        if (colorButtonList.get(i).getButton().getBackground() instanceof GradientDrawable) {

            GradientDrawable gd = (GradientDrawable) drawable.getCurrent();
            gd.setColor(Color.parseColor(colors[i]));

    }
}
    return colorButtonList;
}

为 recyclerView 创建的 Imagebutton。 @drawable/bbtn 形状背景颜色默认设置为黑色

<?xml version="1.0" encoding="utf-8"?>
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/colorbutton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="7dp"
android:layout_marginTop="25dp"
android:layout_marginBottom="25dp"
android:background="@drawable/bbtn">

</ImageButton>

这里是颜色数组。每个按钮都应具有列表之一的不同背景颜色:

  <string-array name="backgroundcolors">
    <item>#000000</item>
    <item>#ffffff</item>
    <item>#373737</item>
    <item>#e6e6e6</item>
    <item>#EAE1D8</item>
    <item>#fd79a1</item>
    <item>#E849A1</item>
    <item>#ff0f68</item>
    <item>#c22032</item>
    <item>#F7E84E</item>
    <item>#0d4b7e</item>
    <item>#329de7</item>
    <item>#68be3f</item>
    <item>#006c35</item>
    <item>#395a4f</item>
    </string-array>

这是我创建 ImageButtons 的类

public class ColorButton{

private ImageButton button;
private String color;
public static List<ColorButton> colorButtonList;


public ColorButton(ImageButton button, String color) {
    this.button = button;
    this.color = color;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public ImageButton getButton() {
    return button;
}

@SuppressLint("NewApi")
public static List<ColorButton> initColorButtons(){
    colorButtonList = new ArrayList<>();

    //here we retrive all colors from color.xml
    Resources resources = App.getAppContext().getResources();
    String colors[] = resources.getStringArray(R.array.backgroundcolors);

    for(int i=0; i<colors.length; i++){
        //Creates 12 ImageButtons with a custom shape
        colorButtonList.add(new ColorButton(new ImageButton(App.getAppContext()), colors[i]));

        //Here each imagebutton should get its own color.
        Drawable drawable = colorButtonList.get(i).getButton().getBackground();

        if (drawable instanceof GradientDrawable) {
            GradientDrawable gd = (GradientDrawable) drawable.getCurrent();
            gd.setColor(Color.parseColor(colors[i]));
        } else if (drawable instanceof RippleDrawable) {
            RippleDrawable rd = (RippleDrawable) drawable;
            // keep in mind that colors[i] should be a string with the hex representation of a color, like: #F4F4F4
            int color = Color.parseColor(colors[i]);
            rd.setColor(newColorStateList(color));
        }
    }
    return colorButtonList;
}


private static ColorStateList newColorStateList(int color) {
    int[][] states = new int[][] {
            new int[] { android.R.attr.state_enabled}, // enabled
            new int[] {-android.R.attr.state_enabled}, // disabled
    };

    int[] colors = new int[] {
            color, color
    };

    return new ColorStateList(states, colors);
}

}

这是来自我的 recyclerView 适配器类,我在其中插入 layout.item_colorbutton。

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    //inflates the custom layout for a button
    View colorButtonView = inflater.inflate(R.layout.item_colorbutton, parent, false);

    //Return a new holder instance of a colorButton
    ViewHolder viewHolder = new ViewHolder(colorButtonView);
    return viewHolder;
}

【问题讨论】:

    标签: android


    【解决方案1】:

    您的问题是,在您的情况下,getBackground() 返回的是 RippleDrawable,而不是 GradientDrawable。两者都扩展了 Drawable,但你不能将一个转换为另一个。 试试这个:

    public List<ImageButton> initColorButtons(){
        colorButtonList = new ArrayList<>();
    
        //here we retrive all colors from color.xml
        Resources resources = App.getAppContext().getResources();
        String colors[] = resources.getStringArray(R.array.backgroundcolors);
    
        for(int i=0; i<colors.length; i++){
            //Creates 12 ImageButtons with a custom shape
            colorButtonList.add(new ColorButton(new ImageButton(App.getAppContext()), colors[i]));
    
            //Here each imagebutton should get its own color.
            Drawable drawable = colorButtonList.get(i).getBackground();
    
            if (drawable instanceof GradientDrawable) {
                GradientDrawable gd = (GradientDrawable) drawable.getCurrent();
                gd.setColor(Color.parseColor(colors[i]));
            } else if (drawable instanceof RippleDrawable) {
                RippleDrawable rd = (RippleDrawable) drawable;
                // keep in mind that colors[i] should be a string with the hex representation of a color, like: #F4F4F4
                int color = Color.parseColor(colors[i]);
                rd.setColor(newColorStateList(color));
            }
        }
        return colorButtonList;
    }
    
    private ColorStateList newColorStateList(int color) {
        int[][] states = new int[][] {
                new int[] { android.R.attr.state_enabled}, // enabled
                new int[] {-android.R.attr.state_enabled}, // disabled
        };
    
        int[] colors = new int[] {
                color, color
        };
    
        return new ColorStateList(states, colors);
    }
    

    结果:

    您可以在this SO question 中阅读有关如何创建 ColorStateList 的更多信息。

    编辑:为了正确修改您使用方法onCreateViewHolder 创建的按钮,您需要在您的适配器中实现onBindViewHolder 并在那里更改按钮的颜色。

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
            Drawable drawable = holder.getBackground();
    
            if (drawable instanceof GradientDrawable) {
                GradientDrawable gd = (GradientDrawable) drawable.getCurrent();
                gd.setColor(Color.parseColor(colors[position]));
            } else if (drawable instanceof RippleDrawable) {
                RippleDrawable rd = (RippleDrawable) drawable;
                int color = Color.parseColor(colors[position]);
                rd.setColor(newColorStateList(color));
            }
    }
    

    【讨论】:

    • 应用程序不再崩溃,但我的 ImageButton 仍然是黑色。我希望它们在运行时都有不同的颜色。我根本不想要 ColorStateList 的任何东西。每个 ImageButton 必须从我的 colors[i] 中拥有自己的颜色,其中包含不同的颜色。
    • ColorStateList 需要更改 RippleDrawable 中的颜色。请更新您的问题,显示您如何创建 ColorStateList,以便我为您提供帮助。
    • @Muddz 您需要添加 else if (drawable instanceof RippleDrawable) { RippleDrawable rd = (RippleDrawable) drawable; rd.setColor(yourColorStateList); } 部分才能使其正常工作,并创建正确的 ColorStateList
    • 嗨。由于最后一个数组:colors,是一个字符串,所以它不接受它,因为它需要一个 int 数组。所以我很快将其修改为:int[] states2 = new int[]{ Color.BLACK, Color.BLUE, Color.CYAN, Color.BLACK, Color.BLUE, Color.CYAN, Color.BLACK, Color.BLUE, Color.CYAN,Color.CYAN,Color.CYAN }; 但颜色没有发生任何变化。所有按钮仍然是黑色的
    • @Muddz 更新了更正 ColorStateList 创建的答案。它对我有用。
    猜你喜欢
    • 1970-01-01
    • 2020-05-14
    • 2016-10-19
    • 2017-04-08
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多