Android Support Palette使用详解

作者:袖梨 2022-06-25

使用Palette API选择颜色

 良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是支持包, 能够从图片中解析出突出的颜色, 从而帮助你创建出视觉迷人的应用

你能够使用Palette包设计布局主题, 并把自定义色彩应用到可视化元素中. 比如, 你可以根据专辑封面, 用Palette创建为歌曲创建一个彩色标题卡片, 或者当应用背景图片发生改变时调整toolbar颜色. Palette对象给予你权限访问Bitmap图片里面的颜色, 同时也根据Bitmap提供了6个主要的颜色, 供你填写设计选择.

设置依赖

Palette为库从版本Android Support Library 24.0.0引入, 可以在build.gradle中按照如下代码添加Palette依赖:

android {
 compileSdkVersion 27
 ...
}

dependencies {
 ...
 implementation 'com.android.support:palette-v7:27.1.1'
}

创建Palette对象

Palette给予你权限访问图片中的基本颜色, 以及重叠文本对应的颜色. 可以根据给定资源图片, 使用palette设计应用风格, 动态改变应用的色彩体系.

要创建Palette, 首先在从Bitmap中实例化Palette.Builder. 然后在生成Palette之前, 可以使用Palette.Builder来自定义Palette.

生成Palette实例

首先, 利用Palette的from(Bitmap)方法从Bitmap中生成Palette.Builder. 之后利用这个Builder同步或者异步地生成Palette. 如果你想在generate()方法被调用的线程中创建Palette对象, 使用同步的palette生成. 如果你想在不同的线程上异步地生成Palette, 就要使用Palette.PaletteAsyncListener.onGenerated方法在Palette生成之后立即访问它.

下面的代码片断展示了两种不同的Palette生成方式:

// Generate palette synchronously and return it
public Palette createPaletteSync(Bitmap bitmap) {
 Palette p = Palette.from(bitmap).generate();
 return p;
}

// Generate palette asynchronously and use it on a different
// thread using onGenerated()
public void createPaletteAsync(Bitmap bitmap) {
 Palette.from(bitmap).generate(new PaletteAsyncListener() {
 public void onGenerated(Palette p) {
  // Use generated instance
 }
 });
}

如果你需要持续为多个有序图片生成多个Palette, 考虑将Palette实例缓存起来, 以避免减缓UI性能. 你也不应该在主线程中创建Palette.

自定义Palette

 Palette.Builder允许你自定义Palette, 通过从结果Palette中选择多少种颜色, Builder使用图片的什么区域生成Palette, Palette中允许什么颜色等. 比如, 你能够过滤掉黑色, 或者, Builder只能够使用图片的上半部分生成Palette.

通过Palette.Builder中的下列方法, 可以微调Palette尺寸和颜色:

  1. addFilter(): 该方法添加了过滤器, 用以表明结果Palette中什么颜色是允许的. 传入自己的Palette.Filter, 修改isAllowed()方法来决定Palette过滤哪些方法.
  2. maximumColorCount(): 该方法设置了Palette中最大的颜色数目. 默认值是16, 最优值依赖于源图. 对于风景图, 最优值处于8~16, 而肖像图通常拥有16~24个值. 颜色越多, Palette.Builder生成Palette就需要花费超久的时间.
  3. setRegion(): 该方法指出了生成Palette时, Builder使用Bitmap的什么区域. 你只能使用这个方法从Bitmap中生成Palette, 而不会影响源图.
  4. addTarget(): 该方法允许你通过向Builder添加Target色彩配置文件来执行自己的颜色匹配. 如果默认的Target并不有效的话, 高级开发人员能够使用Target.Builder创建自己的Target.

提取色彩配置文件

基于材料设计标准, Palette库从图片中提供常用的色彩配置文件. 每一个文件被一个Target定义, 从Bitmap图片中提取的色彩基于饱和度, 亮度和分布(Bitmap中表示色彩的像素数)对文件进行评分. 对于每一个文件, 具有最好分数的颜色定义了给定图片的色彩配置文件.

默认情况下, 对于给定图片, Palette对象包含16个基本颜色. 在生成Palette的时候, 你可以通过Palette.Builder自定义颜色数. 提取更多的色彩对于每个色彩配置文件提供了更多的潜在匹配, 但也引起Palette.Builder花费更久的时间来生成Palette.

Palette库尝试提取以下6个色彩配置文件:

  1. Light Vibrant
  2. Vibrant
  3. Dark Vibrant
  4. Light Muted
  5. Muted
  6. Dark Muted

每一个Palette.getColor()方法返回了Palette中的颜色, 而每一个Palette关联了一个特定的配置文件, 其中, 被以上6个色彩配置文件名取代. 比如, 获取Dark Vibrant色彩配置文件的方法是getDarkVibrantProfile(). 因为不是所有的图片都会包含所有的色彩配置文件, 所以, 你必须也提供一个默认颜色返回.

使用样本创建色彩体系

Palette对象也为每一个色彩配置文件生成 Palette.Swatch对象. Palette.Swatch对象包含对象的配置文件关联的颜色和颜色的像素分布.

Swatch拥有额外的方法来访问色彩配置文件更多的信息, 比如HSL值, 像素分布等. 你能够通过使用getBodyTextColor()和getTitleTextColor()来生成更多繁杂的色彩体系和应用主题. 这些方法返回的颜色恰好配合Swatch的颜色使用.

每一个Palette.getSwatch()方法返回了关联特定配置文件的Swatch. 尽管getSwatch()方法并不默认值参数, 如果图片中并不存在特定的某个配置文件, 该方法会返回null. 由此, 你应该在使用Swatch之前判断它是否为空. 比如, 下面的代码从Palette中获取了标题文本颜色, 并检查了Vibrant Swatch是否为空:

 Palette.Swatch vibrant = myPalette.getVibrantSwatch();
 if(vibrant != null){
  int titleColor = vibrant.getTitleTextColor();
  // ...
 }

要访问Palette中的所有颜色, getSwatches()方法返回了包含图片中生成的所有Swatch的列表, 包括标准的6个色彩配置文件.

下面的代码片断使用了上述代码片断, 同步生成了Palette, 获取了Vibrant Swatch, 改变了Toolbar颜色, 以匹配Bitmap图片. 下面的图片则展示了结果和toolbar

// Set the background and text colors of a toolbar given a
// bitmap image to match
public void setToolbarColor(Bitmap bitmap) {
 // Generate the palette and get the vibrant swatch
 // See the createPaletteSync() method
 // from the code snippet above
 Palette p = createPaletteSync(bitmap);
 Palette.Swatch vibrantSwatch = p.getVibrantSwatch();

 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

 // Load default colors
 int backgroundColor = ContextCompat.getColor(getContext(),
  R.color.default_title_background);
 int textColor = ContextCompat.getColor(getContext(),
  R.color.default_title_color);

 // Check that the Vibrant swatch is available
 if(vibrantSwatch != null){
  backgroundColor = vibrantSwatch.getRgb();
  textColor = vibrantSwatch.getTitleTextColor();
 }

 // Set the toolbar background and text colors
 toolbar.setBackgroundColor(backgroundColor);
  toolbar.setTitleTextColor(textColor);
}

相关文章

精彩推荐