Android Support Palette使用详解
使用Palette API选择颜色
良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是支持包, 能够从图片中解析出突出的颜色, 从而帮助你创建出视觉迷人的应用
你能够使用Palette包设计布局主题, 并把自定义色彩应用到可视化元素中. 比如, 你可以根据专辑封面, 用Palette创建为歌曲创建一个彩色标题卡片, 或者当应用背景图片发生改变时调整toolbar颜色. Palette对象给予你权限访问Bitmap图片里面的颜色, 同时也根据Bitmap提供了6个主要的颜色, 供你填写设计选择.
设置依赖
Palette为库从版本Android Support Library 24.0.0引入, 可以在build.gradle中按照如下代码添加Palette依赖:
1 android { 2 compileSdkVersion 27 3 ... 4 } 5 6 dependencies { 7 ... 8 implementation 'com.android.support:palette-v7:27.1.1' 9 }
创建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生成方式:
1 // Generate palette synchronously and return it 2 public Palette createPaletteSync(Bitmap bitmap) { 3 Palette p = Palette.from(bitmap).generate(); 4 return p; 5 } 6 7 // Generate palette asynchronously and use it on a different 8 // thread using onGenerated() 9 public void createPaletteAsync(Bitmap bitmap) { 10 Palette.from(bitmap).generate(new PaletteAsyncListener() { 11 public void onGenerated(Palette p) { 12 // Use generated instance 13 } 14 }); 15 }
如果你需要持续为多个有序图片生成多个Palette, 考虑将Palette实例缓存起来, 以避免减缓UI性能. 你也不应该在主线程中创建Palette.
自定义Palette
Palette.Builder允许你自定义Palette, 通过从结果Palette中选择多少种颜色, Builder使用图片的什么区域生成Palette, Palette中允许什么颜色等. 比如, 你能够过滤掉黑色, 或者, Builder只能够使用图片的上半部分生成Palette.
通过Palette.Builder中的下列方法, 可以微调Palette尺寸和颜色:
- addFilter(): 该方法添加了过滤器, 用以表明结果Palette中什么颜色是允许的. 传入自己的Palette.Filter, 修改isAllowed()方法来决定Palette过滤哪些方法.
- maximumColorCount(): 该方法设置了Palette中最大的颜色数目. 默认值是16, 最优值依赖于源图. 对于风景图, 最优值处于8~16, 而肖像图通常拥有16~24个值. 颜色越多, Palette.Builder生成Palette就需要花费超久的时间.
- setRegion(): 该方法指出了生成Palette时, Builder使用Bitmap的什么区域. 你只能使用这个方法从Bitmap中生成Palette, 而不会影响源图.
- addTarget(): 该方法允许你通过向Builder添加Target色彩配置文件来执行自己的颜色匹配. 如果默认的Target并不有效的话, 高级开发人员能够使用Target.Builder创建自己的Target.
提取色彩配置文件
基于材料设计标准, Palette库从图片中提供常用的色彩配置文件. 每一个文件被一个Target定义, 从Bitmap图片中提取的色彩基于饱和度, 亮度和分布(Bitmap中表示色彩的像素数)对文件进行评分. 对于每一个文件, 具有最好分数的颜色定义了给定图片的色彩配置文件.
默认情况下, 对于给定图片, Palette对象包含16个基本颜色. 在生成Palette的时候, 你可以通过Palette.Builder自定义颜色数. 提取更多的色彩对于每个色彩配置文件提供了更多的潜在匹配, 但也引起Palette.Builder花费更久的时间来生成Palette.
Palette库尝试提取以下6个色彩配置文件:
- Light Vibrant
- Vibrant
- Dark Vibrant
- Light Muted
- Muted
- Dark Muted
每一个Palette.get<Profile>Color()方法返回了Palette中的颜色, 而每一个Palette关联了一个特定的配置文件, 其中, <Profile>被以上6个色彩配置文件名取代. 比如, 获取Dark Vibrant色彩配置文件的方法是getDarkVibrantProfile(). 因为不是所有的图片都会包含所有的色彩配置文件, 所以, 你必须也提供一个默认颜色返回.
使用样本创建色彩体系
Palette对象也为每一个色彩配置文件生成 Palette.Swatch对象. Palette.Swatch对象包含对象的配置文件关联的颜色和颜色的像素分布.
Swatch拥有额外的方法来访问色彩配置文件更多的信息, 比如HSL值, 像素分布等. 你能够通过使用getBodyTextColor()和getTitleTextColor()来生成更多繁杂的色彩体系和应用主题. 这些方法返回的颜色恰好配合Swatch的颜色使用.
每一个Palette.get<Profile>Swatch()方法返回了关联特定配置文件的Swatch. 尽管get<Profile>Swatch()方法并不默认值参数, 如果图片中并不存在特定的某个配置文件, 该方法会返回null. 由此, 你应该在使用Swatch之前判断它是否为空. 比如, 下面的代码从Palette中获取了标题文本颜色, 并检查了Vibrant Swatch是否为空:
1 Palette.Swatch vibrant = myPalette.getVibrantSwatch(); 2 if(vibrant != null){ 3 int titleColor = vibrant.getTitleTextColor(); 4 // ... 5 }
要访问Palette中的所有颜色, getSwatches()方法返回了包含图片中生成的所有Swatch的列表, 包括标准的6个色彩配置文件.
下面的代码片断使用了上述代码片断, 同步生成了Palette, 获取了Vibrant Swatch, 改变了Toolbar颜色, 以匹配Bitmap图片. 下面的图片则展示了结果和toolbar.
1 // Set the background and text colors of a toolbar given a 2 // bitmap image to match 3 public void setToolbarColor(Bitmap bitmap) { 4 // Generate the palette and get the vibrant swatch 5 // See the createPaletteSync() method 6 // from the code snippet above 7 Palette p = createPaletteSync(bitmap); 8 Palette.Swatch vibrantSwatch = p.getVibrantSwatch(); 9 10 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 11 12 // Load default colors 13 int backgroundColor = ContextCompat.getColor(getContext(), 14 R.color.default_title_background); 15 int textColor = ContextCompat.getColor(getContext(), 16 R.color.default_title_color); 17 18 // Check that the Vibrant swatch is available 19 if(vibrantSwatch != null){ 20 backgroundColor = vibrantSwatch.getRgb(); 21 textColor = vibrantSwatch.getTitleTextColor(); 22 } 23 24 // Set the toolbar background and text colors 25 toolbar.setBackgroundColor(backgroundColor); 26 toolbar.setTitleTextColor(textColor); 27 }