Android Material Design 系列之 Palette 开发详解

2023-10-08 19:59

本文主要是介绍Android Material Design 系列之 Palette 开发详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

Palette 是 Android L SDK 中的新特性,可以使用 Palette 从图像中提取出突出的颜色(主色调),获取到颜色之后我们再将这个颜色值赋给 ActionBar、状态栏等。从而达到界面色调的统一,使界面美观协调。

Palette 原理:通过得到一个 bitmap,通过方法进行分析,取出 LightVibrantSwatch,DarkVibrantSwatch,LightMutedSwatch,DarkMutedSwatch 这些样本,然后得到 rgb 值。

在这里插入图片描述

一、Palette 相关方法

方法介绍
Palette.Builder生成器类,生成 Palette 实例
Palette.Filter过滤器接口,使 Palette 有更加细腻的颜色过滤
Palette.PaletteAsyncListener异步加载监听
pattle.Swatch提供获取结果的色彩样本
from(List<Palette.Switch> switches)通过预设的 Palette.Swatch 颜色样本列表 来生成 Palette
from(Bitmap bitmap)通过返回 Palette.Builder 实例来构建 Palette
palette.getDarkMutedColor(Color.BLUE)获取到柔和的深色的颜色(可传默认值)
palette.getDarkVibrantColor(Color.BLUE)获取到活跃的深色的颜色(可传默认值)
palette.getLightMutedColor(Color.BLUE)获取到柔和的明亮的颜色(可传默认值)
palette.getLightVibrantColor(Color.BLUE)获取到活跃的明亮的颜色(可传默认值)
palette.getVibrantColor(Color.BLUE)获取图片中最活跃的颜色(也可以说整个图片出现最多的颜色)(可传默认值)
palette.getMutedColor(Color.BLUE)获取图片中一个最柔和的颜色(可传默认值)
  • Palette.Builder 生成器类,生成 Palette 实例

  • Palette.Filter 过滤器接口,使 Palette 有更加细腻的颜色过滤

  • Palette.PaletteAsyncListener 异步加载监听

  • pattle.Swatch 提供获取结果的色彩样本

  • from(List<Palette.Switch> switches) 通过预设的 Palette.Swatch 颜色样本列表 来生成 Palette

  • from(Bitmap bitmap) 通过返回 Palette.Builder 实例来构建 Palette

  • palette.getDarkMutedColor(Color.BLUE) 获取到柔和的深色的颜色(可传默认值)

  • palette.getDarkVibrantColor(Color.BLUE) 获取到活跃的深色的颜色(可传默认值)

  • palette.getLightMutedColor(Color.BLUE) 获取到柔和的明亮的颜色(可传默认值)

  • palette.getLightVibrantColor(Color.BLUE) 获取到活跃的明亮的颜色(可传默认值)

  • palette.getVibrantColor(Color.BLUE) 获取图片中最活跃的颜色(也可以说整个图片出现最多的颜色)(可传默认值)

  • palette.getMutedColor(Color.BLUE) 获取图片中一个最柔和的颜色(可传默认值)

二、基本使用

1、导入依赖

implementation 'androidx.palette:palette:1.0.0'

2、Palette 创建

Palette 创建有同步和异步两种方式,开发中我们为了提高应用性能,比较耗时的操作都会采用异步方式。

Bitmap bm =BitmapFactory.decodeResource(getResources(),R.drawable.kale);
// 同步
Palette.Builder builder = Palette.from(bm);
Palette palette=builder.generate();
// 异步
builder.generate(bitmap, new Palette.PaletteAsyncListener() {@Overridepublic void onGenerated(Palette palette) {}
}

3、Palette 获取颜色属性

Palette 可以分析提取出以下突出的颜色,在应用适用的环境下灵活使用,如下图所示,获取到屏幕中图片 BitMap 对象,然后通过 Palette 提取到相关属性,在 TextView 设置背景颜色。

Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {@Overridepublic void onGenerated(@Nullable Palette palette) {//获取到柔和的深色的颜色(可传默认值)int darkMutedColor = palette.getDarkMutedColor(Color.BLUE);//如果分析不出来,则返回默认颜色//获取到柔和的明亮的颜色(可传默认值)int lightMutedColor = palette.getLightMutedColor(Color.BLUE);//获取到活跃的深色的颜色(可传默认值)int darkVibrantColor = palette.getDarkVibrantColor(Color.BLUE);//获取到活跃的明亮的颜色(可传默认值)int lightVibrantColor = palette.getLightVibrantColor(Color.BLUE);//获取图片中一个最柔和的颜色(可传默认值)int mutedColor = palette.getMutedColor(Color.BLUE);//获取图片中最活跃的颜色(也可以说整个图片出现最多的颜色)(可传默认值)int vibrantColor = palette.getVibrantColor(Color.BLUE);//获取某种特性颜色的样品Palette.Swatch lightVibrantSwatch = palette.getVibrantSwatch();//谷歌推荐的:图片的整体的颜色rgb的混合值---主色调int rgb = lightVibrantSwatch.getRgb();//谷歌推荐:图片中间的文字颜色int bodyTextColor = lightVibrantSwatch.getBodyTextColor();//谷歌推荐:作为标题的颜色(有一定的和图片的对比度的颜色值)int titleTextColor = lightVibrantSwatch.getTitleTextColor();//颜色向量float[] hsl = lightVibrantSwatch.getHsl();//分析该颜色在图片中所占的像素多少值int population = lightVibrantSwatch.getPopulation();tv1.setText("darkMutedColor");tv1.setBackgroundColor(darkMutedColor);tv2.setText("lightMutedColor");tv2.setBackgroundColor(lightMutedColor);tv3.setText("darkVibrantColor");tv3.setBackgroundColor(darkVibrantColor);tv4.setText("lightVibrantColor");tv4.setBackgroundColor(lightVibrantColor);tv5.setText("mutedColor");tv5.setBackgroundColor(mutedColor);tv6.setText("vibrantColor");tv6.setBackgroundColor(vibrantColor);}
});

三、Palette + CardView 案例

通过上述简单介绍,我们已经大致清除 Palette 是干什么的,接下来就根据开发中常见需求实现效果。

在列表页加载卡片的情况下,经常会在图片底部或者顶部添加一片半透明区域,用来显示文本信息,以前常规做法是设置一个半透明颜色,但是这种做法在暗灰色的图片上,展示效果极差。Google 提供 Palette 之后,就可以根据图片分析出最适合的底色作为背景色,让图片和整列表更加优雅的展示。

本文主要内容是 Palette,如果对 CardView 不熟悉的朋友可以查看前文:

1、颜色样本

创建完一个 Palette 实例之后,我们还需要得到一种采集的样本(swatch),有 6 中样本(swatch)

  • Palette.getVibrantSwatch() 返回一个鲜明(有活力)的样本类
  • Palette.getDarkVibrantSwatch() 返回一个鲜明(有活力)的暗色调样本类
  • Palette.getLightVibrantSwatch() 返回一个鲜明(有活力)的亮色调样本类
  • Palette.getMutedSwatch() 返回一个柔和的样本类
  • Palette.getDarkMutedSwatch() 返回一个柔和的暗色调样本类
  • Palette.getLightMutedSwatch() 返回一个柔和的亮色调样本类

2、创建鲜明(有活力)的样本类

以上 6 种样本色调使用方式一模一样,这里用getVibrantSwatch()举例说明,其他用法自行上手练习。

//获取某种特性颜色的样品
Palette.Swatch lightVibrantSwatch = palette.getVibrantSwatch();
if (lightVibrantSwatch == null) {for (Palette.Swatch swatch : palette.getSwatches()) {lightVibrantSwatch = swatch;break;}
}
//谷歌推荐的:图片的整体的颜色rgb的混合值---主色调
int rgb = lightVibrantSwatch.getRgb();
//谷歌推荐:图片中间的文字颜色
int bodyTextColor = lightVibrantSwatch.getBodyTextColor();
//谷歌推荐:作为标题的颜色(有一定的和图片的对比度的颜色值)
int titleTextColor = lightVibrantSwatch.getTitleTextColor();

注意:getVibrantSwatch()方法返回的 Palette.Swatch 对象有可能为 null,所以一定要判断是否为 null,否则可能会抛出NullPointerException异常。

3、设置颜色透明度

当我们获取到图片的整体的颜色 rgb 的混合值,这个值就是跟图片最接近的颜色,也是 Google 官方推荐使用的主色调,要想达到前文中降的效果,应用时还需对 rgb 值进行透明后再使用。

/*** @param percent   透明度* @param rgb   RGB值* @return 最终设置过透明度的颜色值*/
protected int getTranslucentColor(float percent, int rgb) {int blue = Color.blue(rgb);int green = Color.green(rgb);int red = Color.red(rgb);int alpha = Color.alpha(rgb);alpha = Math.round(alpha * percent);return Color.argb(alpha, red, green, blue);
}

4、加载网络图片

因为发现很多文章都是采用本地资源库图片,获取 BitMap 方式比较简单,在实际项目中,如果加载网络图片的话,可以使用 Glide.asBitMap() 方法来实现,这里使用了一个 Adapter 的三方库,防止朋友们看懵逼,贴上 Adapter 完整代码,如果想学习的小伙伴,建议在文末下载源码学习。

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/cardView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:clickable="true"android:focusable="true"android:foreground="@drawable/item_touch_bg"app:cardCornerRadius="1dp"app:cardElevation="1dp"app:cardPreventCornerOverlap="false"app:cardUseCompatPadding="true"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/articleListImg"android:layout_width="match_parent"android:layout_height="200dp"android:contentDescription="@null"android:scaleType="centerCrop"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"tools:src="@drawable/ic_launcher_background" /><TextViewandroid:id="@+id/articleListTitle"android:layout_width="match_parent"android:layout_height="70dp"android:gravity="center"android:textColor="@color/white"android:textSize="18dp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="@+id/articleListImg"app:layout_constraintStart_toStartOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout></androidx.cardview.widget.CardView>
public class PaletteImageAdapter extends BaseCompatAdapter<ArticleBean, BaseViewHolder> {public PaletteImageAdapter(int layoutResId, List<ArticleBean> data) {super(layoutResId, data);}@Overrideprotected void convert(BaseViewHolder helper, ArticleBean item) {// 使用Glide.asBitmap()方法转换FutureTarget<Bitmap> bitmap = Glide.with(mContext).asBitmap().load(item.getImageUrl()).submit();// 在子线程中执行提取颜色任务,Palette提取颜色根据图片质量耗时不同,属于比较耗时的操作new Thread(() -> {try {setPalette(bitmap.get(), helper, item);} catch (Exception e) {e.printStackTrace();}}).start();}private void setPalette(Bitmap bitmap, BaseViewHolder helper, ArticleBean item) {Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {@Overridepublic void onGenerated(@Nullable Palette palette) {//获取某种特性颜色的样品Palette.Swatch lightVibrantSwatch = palette.getVibrantSwatch();if (lightVibrantSwatch == null) {for (Palette.Swatch swatch : palette.getSwatches()) {lightVibrantSwatch = swatch;break;}}//谷歌推荐的:图片的整体的颜色rgb的混合值---主色调int rgb = lightVibrantSwatch.getRgb();//谷歌推荐:图片中间的文字颜色int bodyTextColor = lightVibrantSwatch.getBodyTextColor();//谷歌推荐:作为标题的颜色(有一定的和图片的对比度的颜色值)int titleTextColor = lightVibrantSwatch.getTitleTextColor();helper.setText(R.id.articleListTitle, item.getTitle()).setTextColor(R.id.articleListTitle, titleTextColor).setBackgroundColor(R.id.articleListTitle, getTranslucentColor(0.8f, rgb));((ImageView) helper.getView(R.id.articleListImg)).setImageBitmap(bitmap);}});}
}


在这里插入图片描述

四、Palette 注意事项

其实前面代码注释里已经提到了,Palette 加载不能在主线程中进行,如果是列表展示图片时,会报错。因为 Palette 提取图片色彩的操作是比较耗时的,所以一定要在子线程中执行。

加载方式有同步加载和异步加载两种:

1、同步加载

由于他们很可能会比较耗时(在分析大图片或者所需颜色较多时),所以它们不应该在主线程中执行。你应该先在别的线程中使用这两个函数进行解析,解析成功之后再使用。

2、异步加载

有时候你不会在加载图片的线程(非主线程)中使用解析出的颜色,所以 Palette 提供了异步方法,他们与之前的函数的区别就是需要传入 PaletteAsyncListener,提供在图片解析完成后的回调函数。

源码下载    源码包含 Material Design 系列控件集合,定时更新,敬请期待!

总结

现在很多流行的 APP 列表界面垂直滑动时,会根据内容色调动态更改 ToolBar 的颜色,这种效果就可以借助 Palette 来采取图片颜色实现。其实 Palette 并不只适用于我写的示例,Palette 应用的情况很多,感兴趣的朋友可以在官网详细学习!

我的微信:Jaynm888

欢迎点评,诚邀 Android 程序员加入微信交流群,公众号回复加群或者加我微信邀请入群。

这篇关于Android Material Design 系列之 Palette 开发详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/167659

相关文章

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例: