<七>Drawables的使用(一)

以下从三个方面进行介绍Drawables:

* Drawable tinting (着色)
* Prominent color extraction(颜色提取)
* Vector drawables(矢量图片)

Tint Drawable Resources

以下部分介绍转自:http://segmentfault.com/a/1190000003038675?utm_source=tuicool&utm_medium=referral

什么是Tint
当我开始接触Tint这个词的时候,其实是蛮不理解它的意思的,以及并不清楚Google发明它的目的,它一般搭配Background配合使用,但是现在已经有了Background,为什么还需要Tint呢?
Tint 翻译为着色。
着色,着什么色呢?和背景有关,当然是着背景的色。当我开发客户端,使用了appcompat-v7包的时候,为了实现Material
Design的效果,我们会去设置主题里的几个颜色,重要的比如primaryColor,colorControlNormal,colorControlActived
等等,而我们使用的一些组件,比如EditText就会自动变成我们想要的背景颜色,在背景图只有一张的情况下,这样的做法极大的减少了我们apk包的大小。
实现的方式就是用一个颜色为我们的背景图片设置tint(着色)。 例子:

看看即将发布的SegmentFault for Android
2.7中,发布问题功能,这个EditText的颜色和我们的主要颜色相同。它利用了TintManager这个类,为自己的背景进行着色(绿色)。 那么这个原始图是什么样子呢?我们从appcompat-v7包中找到了这个图,是一个.9图,样子如下:

其实它只是一个黑色的条,通过绿色的着色,变成了一个绿色的条。 就是这样的设计方式,使得我们在Material
Design中省了多少资源文件呀! 好了,既然理解了tint的含义,我们赶紧看下这一切是如何实现的吧。
其实底层特别简单,了解过渲染的同学应该知道PorterDuffColorFilter这个东西,我们使用SRC_IN的方式,对这个Drawable进行颜色方面的渲染,就是在这个Drawable中有像素点的地方,再用我们的过滤器着色一次。
实际上如果要我们自己实现,只用获取View的backgroundDrawable之后,设置下colorFilter即可。
看下最核心的代码就这么几行
if (filter == null) {
// Cache miss, so create a color filter and add it to the cache
filter = new PorterDuffColorFilter(color, mode);
}

 d.setColorFilter(filter); d.setColorFilter(filter); 由于API Level 21以前不支持background

tint在xml中设置(android:tint和android:tintMod),于是提供了ViewCompat.setBackgroundTintList方法和ViewCompat.setBackgroundTintMode用来手动更改需要着色的颜色,但要求相关的View继承TintableBackgroundView接口。

TintMode的类型有以下16种:
这里写图片描述
1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC 显示上层绘制图片
3.PorterDuff.Mode.DST 显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR 异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN 取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN 取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY 取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN 取两图层全部区域,交集部分变为透明色

从图像中提取颜色(Palette)

Android Support Library r21 r21 及更高版本提供了Palette 类,以便我们从图像提取颜色,主要的颜色类型有以下六种:

* vibrant(鲜艳色)
* dark vibrant(鲜艳色中的暗色)
* light vibrant(鲜艳色中的亮色)
* muted(柔和色)
* dark muted(柔和色中的暗色)
* light muted(柔和色中的亮色)    

###使用:

1.首先需要添加依赖:

dependencies {
    ...
    compile 'com.android.support:palette-v7:21.0.0'
}

2.创建示例

  • 同步方法(尽量避免在主线程中使用):
Palette p = Palette.from(bitmap).generate();
  • 异步方法(在异步线程中执行完之后通过监听器回调)
 // Asynchronous
 Palette.from(bitmap).generate(new PaletteAsyncListener() {
     public void onGenerated(Palette p) {
         // Use generated instance
     }
 });

3.获取颜色

  • 通过提供的getter函数直接获取以上提及的六种类型颜色:
  Palette palette = Palette.from(bitmap).generate();
      int vibrant = palette.getVibrantColor(0x000000);
      int vibrantLight = palette.getLightVibrantColor(0x000000);
      //提取失败则返回指定的颜色:0x000000
      ......
  • 通过Swatch对象提取(Swatch里面含有很多关于对应颜色的有用信息)
 Palette palette = Palette.from(bitmap).generate();
   Palette.Swatch swatch = palette.getVibrantSwatch();
   //rgb颜色值
   int rgbColor = swatch.getRgb();
   //hsl颜色向量
   float[] hslValues = swatch.getHsl();
   //该颜色在图像中所占的像素数
   int pixelCount = swatch.getPopulation();
   //对应的标题字体颜色
   int titleTextColor = swatch.getTitleTextColor();
   //对应的正文字体颜色
   int bodyTextColor = swatch.getBodyTextColor();

4:来自网上的一张demo示例图:
这里写图片描述

矢量图片(Vector Drawables)

见下一章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值