以编程方式生成Material Design颜色集的方法有哪些?

时间:2015-01-18 16:43:47

标签: java android colors material-design

我正在尝试创建一个Material Design的调色板,用任意颜色的十六进制来改变亮度/亮度百分比。说到实现,我发现有一些我无法生成的颜色十六进制,并显示Color Unknown Exception。您能告诉我生成这组颜色的替代方案或技术预防措施是什么?

enter image description here 以下是我的代码

package com.example.dino.util;

import android.content.Context;
import android.graphics.Color;

import java.util.ArrayList;

/**
 * Created by larrylo on 18/1/15.
 */

public  class ColorUtils {

    public Context context;

    public static float[]  colorToHsl(String hexColor) {
        int color = Color.parseColor(hexColor);
        float r = ((0x00ff0000 & color) >> 16) / 255.0F;
        float g = ((0x0000ff00 & color) >> 8) / 255.0F;
        float b = ((0x000000ff & color)) / 255.0F;
        float max = Math.max(Math.max(r, g), b);
        float min = Math.min(Math.min(r, g), b);
        float c = max - min;

        float hTemp = 0.0F;
        if (c == 0) {
            hTemp = 0;
        } else if (max == r) {
            hTemp = (float) (g - b) / c;
            if (hTemp < 0)
                hTemp += 6.0F;
        } else if (max == g) {
            hTemp = (float) (b - r) / c + 2.0F;
        } else if (max == b) {
            hTemp = (float) (r - g) / c + 4.0F;
        }
        float h = 60.0F * hTemp;

        float l = (max + min) * 0.5F;

        float s;
        if (c == 0) {
            s = 0.0F;
        } else {
            s = c / (1 - Math.abs(2.0F * l - 1.0F));
        }

        float []  hsl  = {h , s , l } ;
        return hsl;
    }



    public static String hslToColor(int alpha, float hue, float saturation, float lightness) {
        float hh = hue;
        float ss = saturation;
        float ll = lightness;
        float h, s, v;
        h = hh;
        ll *= 2;
        ss *= (ll <= 1) ? Ll : 2 - ll;
        v = (ll + ss) / 2;
        s = ((ll + ss) != 0) ? (2 * ss) / (ll + ss) : 0;
        int resultColorInt =  Color.HSVToColor(alpha, new float[] { h, s, v });
        return Integer.toHexString(resultColorInt).toUpperCase();
    }

    public static ArrayList<String> returnMaterialDesignColorSet (String colorHex){
        ArrayList<String> resultList = new ArrayList<String>();
        float [] baseColorHSL = colorToHsl(colorHex);
        double randomMid = randomWithRange(0.48 , 0.52);
        String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);
        resultList.add(baseColor);
        return resultList;
    }

    public static double randomWithRange(double min, double max)
    {
        double range = Math.abs(max - min);
        return (Math.random() * range) + (min <= max ? Min : max);
    }

    public static int colorInt (String hex){
        return Color.parseColor(hex);
    }
}

测试代码

 ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
        double max = 0.52;
        double min = 0.48;
        double range = Math.abs(max - min);
        double value =  (Math.random() * range) + (min <= max ? Min : max);
        float result = (float)value;
        System.out.println(result);
        String test  = "#973f5c";
        String test2 = ColorUtils.returnMaterialDesignColorSet(test).get(0);
        int colorInt = ColorUtils.colorInt(test2);

        actionBar .setBackgroundDrawable(new ColorDrawable(colorInt));

2 个答案:

答案 0 :(得分:6)

原始问题

您的代码在使用颜色格式时出错。 替换hslToColor()的最后一行,如下所示,您将使其无误地运行:

public static String hslToColor(int alpha, float hue, float saturation, float lightness) {

    ...

    // !!! ERROR WAS ON THE LAST LINE:
    return String.format("#%08x", resultColorInt).toUpperCase();
}

我测试了它 - 它的工作原理 - 因为它增加了两件事:
1)格式值为8位数 2)添加“”前缀

代码中可能出现的第二个问题

alpha值可以具有从0(透明)到255(不透明)的值。如果你想要不透明图像,你应该传递255(0xFF) 现在你传递1我认为这是一个错误 - 因为它几乎是透明的。
所以要有不透明的颜色替换线

String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);

String baseColor = hslToColor(0xFF ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);

附件
如果需要获得一组颜色 - 应该应用一点创造力 要创建色调调色板,您必须更改循环 a)饱和度或 b)亮度或 c)两者。
这是一个实现示例,它基于亮度从0.4到0.6(非包含)的10个步骤返回调色板 “实验”意味着你应该为自己找到价值。

public static ArrayList<String> returnMaterialDesignColorSet(String baseColorHex, int colorCount) {
    ArrayList<String> resultList = new ArrayList<String>();
     float [] baseColorHSL = colorToHsl(baseColorHex);

    float lght=0.4;// initial lightness value (experimental)
    float lStep=(0.6 - lght) / colorCount; // step to go up to 0.6 lightness (experimental)
    for (int i = 0; i < colorCount; i++) {
         String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , lght);
         resultList.add(baseColor);
         lght += lStep;
    }

    return resultList;
}

答案 1 :(得分:0)

问题在于以下几行:

int resultColorInt =  Color.HSVToColor(alpha, new float[] { h, s, v });
return Integer.toHexString(resultColorInt).toUpperCase();

当alpha值小于16(0xF0)时,它将只占用字符串中的一个字符:

// 1-char alpha
int resultColorInt =  Color.HSVToColor(1, new float[]{340, 0.7f, 0.5f});
String result = Integer.toHexString(resultColorInt).toUpperCase();
// result == "1802644" - 7 chars, which is invalid color format

你需要通过在结果字符串的开头附加0来补偿1-char或0-char alphas(在0-15范围内):

// not the best code, but works
while (result.length() < 8) {
    result = "0" + result;
}

// don't forget # to make it a legal color
result = "#" + result;
return result;

然而,最好的办法是完全避免使用字符串。而是使用ints - 它们包含具有更好性能的相同数据。为方便起见,在调试器中,您可以更改以HEX显示的整数,而不是DEC(在Android Studio中:右键单击“变量”视图,“查看为 - &gt; HEX”)。