平铺 Drawable 元素

        如果希望在运行时对基础资源动态改变颜色,避免重复仅在颜色方面有所变化的常见资源。则可以使用颜色滤镜,对任意 Drawable 实例应用颜色遮罩。

        Drawable 颜色滤镜通常是完全不透明的,但 Android 框架还支持通过 PorterDuff.XferMode 进行部分混合。只可以从 Java 代码中执行此方法。


        下面的是没有加颜色滤镜时的输出:


       下面是加了颜色滤镜后的输出 :




content_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="8dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.crazy.colorfilters.MainActivity"
    tools:showIn="@layout/activity_main">

    <ImageView
        android:id="@+id/icon_marker"
        android:layout_weight="1"
        android:src="@drawable/eqc"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_gtx"
        android:layout_weight="1"
        android:src="@drawable/gtx"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_lik"
        android:layout_weight="1"
        android:src="@drawable/epr"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_mvh"
        android:layout_weight="1"
        android:src="@drawable/lre"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
</LinearLayout>




ColorFilterActivity.java :

package com.crazy.colorfilters;

import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;

public class ColorFilterActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

        applyIconFilters();
    }

    private void applyIconFilters(){
        ImageView iconView = (ImageView)findViewById(R.id.icon_marker);
        // 绘制纯紫色图标
        iconView.getDrawable().mutate().setColorFilter(0xFFAA00AA, PorterDuff.Mode.SRC_ATOP);

        iconView = (ImageView)findViewById(R.id.icon_gtx);
        // 绘制纯绿色图标
        iconView.getDrawable().mutate().setColorFilter(0xFF00AA00, PorterDuff.Mode.SRC_ATOP);

        iconView = (ImageView)findViewById(R.id.icon_lik);
        // 绘制纯蓝色图标(部分透明)
        iconView.getDrawable().mutate().setColorFilter(0xFF0000AA, PorterDuff.Mode.MULTIPLY);

        iconView = (ImageView)findViewById(R.id.icon_mvh);
        // 绘制纯红色图标(部分透明)
        iconView.getDrawable().mutate().setColorFilter(0xFFAA0000, PorterDuff.Mode.MULTIPLY);
    }
}

       使用 setColorFilter() 方法,可以通过色调绘制任何 Drawable 。该方法可以接受 ARGB 颜色值和 PorterDuff.Mode 以进行像素变换和混合。选择 SRC_ATOP 确保完全绘制所选的颜色并忽略原始的图片像素。

       如果基础图片存在要露出来的变化情况(如渐变),可以取部分透明地滤镜颜色和/或者尝试使用不同的 PorterDuff.Mode 值,如上面的 MULTIPLY。


       如果在同一个 Activity 中(例如在列表中)多次重复使用相同的图片资源,并且尝试设置多个色调值,就会发现所有 Drawable 将仅显示最近设置的颜色。这是因为存在所谓的共享恒定状态。因为这样可以节约内存资源。然而,这种假设的负面效果就是更改某个 Drawable 状态的属性也会影响所有其他的 Drawable 。为避免出现这种问题,在进行影响单个 Drawable 状态的修改时,都应首先调用其 mutate() 方法。如代码所示。


       注意:Drawable 通常只可变化一次,因此最好不要将此方法用作复制或者克隆机制。



       从 Android5.0 开始,可以使用 android:tint 属性或者在代码中通过 setTint() 方法,从 XML 中将相同的效果应用于多个 Drawable。代码如下:

      在 res/drawable 目录下:

tinted_marker.xml :

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/eqc"
    android:tint="#FFAA00AA"/>

tinted_gtx.xml :

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/gtx"
    android:tint="#FF00AA00">

</bitmap>

tinted_epr.xml :

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/epr"
    android:tint="#FF0000AA">

</bitmap>

tinted_lre :

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/lre"
    android:tint="#FFAA0000">

</bitmap>


content_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="8dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.crazy.colorfilters.MainActivity"
    tools:showIn="@layout/activity_main">

    <ImageView
        android:id="@+id/icon_marker"
        android:layout_weight="1"
        android:src="@drawable/tinted_marker"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_gtx"
        android:layout_weight="1"
        android:src="@drawable/tinted_gtx"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_lik"
        android:layout_weight="1"
        android:src="@drawable/tinted_epr"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/icon_mvh"
        android:layout_weight="1"
        android:src="@drawable/tinted_lre"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
</LinearLayout>



ColorFilterActivity.java :

package com.crazy.colorfilters;

import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;

public class ColorFilterActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

   //     applyIconFilters();
    }

  /*  private void applyIconFilters(){
        ImageView iconView = (ImageView)findViewById(R.id.icon_marker);
        // 绘制纯紫色图标
        iconView.getDrawable().mutate().setColorFilter(0xFFAA00AA, PorterDuff.Mode.SRC_ATOP);

        iconView = (ImageView)findViewById(R.id.icon_gtx);
        // 绘制纯绿色图标
        iconView.getDrawable().mutate().setColorFilter(0xFF00AA00, PorterDuff.Mode.SRC_ATOP);

        iconView = (ImageView)findViewById(R.id.icon_lik);
        // 绘制纯蓝色图标(部分透明)
        iconView.getDrawable().mutate().setColorFilter(0xFF0000AA, PorterDuff.Mode.MULTIPLY);

        iconView = (ImageView)findViewById(R.id.icon_mvh);
        // 绘制纯红色图标(部分透明)
        iconView.getDrawable().mutate().setColorFilter(0xFFAA0000, PorterDuff.Mode.MULTIPLY);
    }*/
}


因为不在有之前应用于滤镜的 Java 代码,所以效果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值