【问题标题】:Convert colorPrimary to colorPrimaryDark (how much darker)将 colorPrimary 转换为 colorPrimaryDark(暗多少)
【发布时间】:2015-09-01 10:11:00
【问题描述】:

在 Material Design 的指导下,状态栏应该比操作栏暗多少? 我在运行时为操作栏设置了颜色,并且在编程时无法知道该颜色,那么如何获得正确的状态栏颜色?

我知道我可以用这个来加深颜色

this.getSupportActionBar().setBackgroundDrawable(new ColorDrawable(colorPrimary));                              
float[] hsv = new float[3];
Color.colorToHSV(colorPrimary, hsv);
hsv[2] *= 0.8f;
int colorPrimaryDark = Color.HSVToColor(hsv);

if(Build.VERSION.SDK_INT>=21)
    Chat.this.getWindow().setStatusBarColor(colorPrimaryDark);

但我不确定要变暗多少

【问题讨论】:

    标签: java android material-design


    【解决方案1】:

    官方Material Color Tool根据JS库chroma.js计算变暗/变亮颜色,使用chroma.darken() / chroma.brighten()函数,其算法基于CIELAB color space

    来自 Github 上 source code 的 sn-p

    Color.prototype.darken = function(amount=1) {
      const me = this;
      const lab = me.lab();
      lab[0] -= LAB_CONSTANTS.Kn * amount;
      return new Color(lab, 'lab').alpha(me.alpha(), true);
    }
    

    Material Color Tool 只是使用了数量参数的后备值,而LAB_CONSTANTS.Kn 是 18,它在 亮度分量 L 上减去 18(变暗)/加 18(变亮) * 给定的基色。

    【讨论】:

      【解决方案2】:

      Android java 代码:

      public static int darkenColor(int color) {
          int alpha = Color.alpha(color);
          int red = Color.red(color);
          int green = Color.green(color);
          int blue = Color.blue(color);
      
          return Color.argb(alpha, (int) (red * 0.9), (int) (green * 0.9), (int) (blue * 0.9));
      }
      
      public static String intColor2String(int intColor) {
          String strColor = String.format("#%06X", 0xFFFFFF & intColor);
          return strColor;
      }
      

      如何使用?

      String dakenColor = Utils.intColor2String(
              Utils.darkenColor(Color.parseColor("#21BBA6")));
      

      【讨论】:

      • 欢迎来到 SO!当您发布主要包含代码的答案时,请尝试解释一下。这段代码是如何工作的?这个POV有哪些优势:?
      【解决方案3】:

      使用Material Color Tool 可以准确地知道它应该变暗多少。只需输入原色的十六进制值,它就会为您生成浅色和深色版本。

      【讨论】:

      • 我正在寻找一种以编程方式执行此操作的方法,因为我正在从可能是任何图像的图像生成主图像。但无论如何,谢谢,这看起来是一个很好的资源
      • 这里是材质颜色工具的直接链接:material.io/tools/color/#!/…。在页面上,点击 CUSTOM 链接(位于右上角附近)并输入您的十六进制颜色以显示该颜色的明暗变化(以及十六进制值)。
      【解决方案4】:

      材质设计调色板不是通过在 HSV 中操作颜色生成的。它是使用 HSL(色相、饱和度、亮度)完成的。

      这是一个使用 HSL 使颜色变暗/变亮的实用程序类

      package com.ammar.materialcolorizer;
      
      import android.graphics.Color;
      
      /**
       * A utility class for darkening and lightening colors in the same way as
       * material design color palettes
       * Created by Ammar Mardawi on 12/4/16.
       */
      
      public class ColorUtil {
      
          /**
           * Darkens a given color
           * @param base base color
           * @param amount amount between 0 and 100
           * @return darken color
           */
          public static int darken(int base, int amount) {
              float[] hsv = new float[3];
              Color.colorToHSV(base, hsv);
              float[] hsl = hsv2hsl(hsv);
              hsl[2] -= amount / 100f;
              if (hsl[2] < 0)
                  hsl[2] = 0f;
              hsv = hsl2hsv(hsl);
              return Color.HSVToColor(hsv);
          }
      
          /**
           * lightens a given color
           * @param base base color
           * @param amount amount between 0 and 100
           * @return lightened
           */
          public static int lighten(int base, int amount) {
              float[] hsv = new float[3];
              Color.colorToHSV(base, hsv);
              float[] hsl = hsv2hsl(hsv);
              hsl[2] += amount / 100f;
              if (hsl[2] > 1)
                  hsl[2] = 1f;
              hsv = hsl2hsv(hsl);
              return Color.HSVToColor(hsv);
          }
      
      
          /**
           * Converts HSV (Hue, Saturation, Value) color to HSL (Hue, Saturation, Lightness)
           * Credit goes to xpansive
           * https://gist.github.com/xpansive/1337890
           * @param hsv HSV color array
           * @return hsl
           */
          private static float[] hsv2hsl(float[] hsv) {
              float hue = hsv[0];
              float sat = hsv[1];
              float val = hsv[2];
      
              //Saturation is very different between the two color spaces
              //If (2-sat)*val < 1 set it to sat*val/((2-sat)*val)
              //Otherwise sat*val/(2-(2-sat)*val)
              //Conditional is not operating with hue, it is reassigned!
              // sat*val/((hue=(2-sat)*val)<1?hue:2-hue)
              float nhue = (2f - sat) * val;
              float nsat = sat * val / (nhue < 1f ? nhue : 2f - nhue);
              if (nsat > 1f)
                  nsat = 1f;
      
              return new float[]{
                      //[hue, saturation, lightness]
                      //Range should be between 0 - 1
                      hue, //Hue stays the same
      
                      // check nhue and nsat logic
                      nsat,
      
                      nhue / 2f //Lightness is (2-sat)*val/2
                      //See reassignment of hue above
              };
          }
      
          /**
           * Reverses hsv2hsl
           * Credit goes to xpansive
           * https://gist.github.com/xpansive/1337890
           * @param hsl HSL color array
           * @return hsv color array
           */
          private static float[] hsl2hsv(float[] hsl) {
              float hue = hsl[0];
              float sat = hsl[1];
              float light = hsl[2];
      
              sat *= light < .5 ? light : 1 - light;
      
              return new float[]{
                      //[hue, saturation, value]
                      //Range should be between 0 - 1
      
                      hue, //Hue stays the same
                      2f * sat / (light + sat), //Saturation
                      light + sat //Value
              };
          }
      }
      

      根据Material Design Color Generator,要生成primaryColorDark,需要变暗12。下面是如何生成与Material Design Color Generator完全一样的全调色板:

          setColor("50", ColorUtil.lighten(color, 52), mTv50);
          setColor("100", ColorUtil.lighten(color, 37), mTv100);
          setColor("200", ColorUtil.lighten(color, 26), mTv200);
          setColor("300", ColorUtil.lighten(color, 12), mTv300);
          setColor("400", ColorUtil.lighten(color, 6), mTv400);
      
          setColor("500", ColorUtil.lighten(color, 0), mTv500);
      
          setColor("600", ColorUtil.darken(color, 6), mTv600);
          setColor("700", ColorUtil.darken(color, 12), mTv700);
          setColor("800", ColorUtil.darken(color, 18), mTv800);
          setColor("900", ColorUtil.darken(color, 24), mTv900);
      

      【讨论】:

        【解决方案5】:

        恕我直言,它应该有多“黑暗”,这取决于你自己。

        如果你使用的是Android Studio,在colors.xml中,双击颜色预览,切换到HSV模式,降低亮度。 (类似于您以编程方式执行的操作)

        【讨论】:

        • 我会降低多少
        • 由你决定......你更喜欢什么,什么可以与你的主要组合完美结合。在这种情况下,也许您不应该严格遵循指南,建议不能适用于所有颜色
        • 好点,指南不是不是规则。但这并不能真正回答问题。
        • @shkschneider 谢天谢地,他从你那里得到了正确的答案。我接受我的回答是基于意见的
        【解决方案6】:

        Google 建议将 500 种颜色用作应用中的原色,将其他颜色用作强调色。

        工具栏和较大的色块应使用应用主色的 500 色。

        所以 primaryColor 应该是 tint 500。

        状态栏应该是原色的深 700 色调。

        所以 primaryColorDark 应该是 tint 700。

        所以我猜primaryColorDark应该比primaryColor暗200色。

        https://www.google.com/design/spec/style/color.html

        【讨论】:

        • 对。但如果我知道 500 的颜色代码,我将如何以编程方式将其转换为 700?
        • 如果你有 tint 500 color,你可以像这样使用 RGB:R*0.7, G*0.7, B*0.7 来获得 tint 700 color。
        • 500和700是调色板,但他已经选好了颜色,可能不是500。你从一开始就没有严格遵守规则
        • 指南不是规则。 OP:取一个颜色,使用 *0.5 和 *0.7 RB 比率来获得一个漂亮的、MD 友好的渐变。无论如何,其余的取决于您。
        • 将 RGB 值乘以 0.7 并不是使颜色变暗的一致方法,而且他们并没有以这种方式从 500 种颜色中导出 700 种颜色。根据您变暗的颜色,某些颜色会比其他颜色变暗得多。实现此目的的更好方法是将 rgb 转换为 HSL 颜色空间,然后根据您希望它变暗的程​​度从亮度值中减去,然后再转换回 rgb。
        猜你喜欢
        • 1970-01-01
        • 2018-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-09
        • 2021-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多