android中如何在低版本(5.0之前)上使用tint(着色)属性

1. 使用app前缀(app:backgroundTint,app:backgroundTintMode),如果使用android前缀,在低版本上是拿不到值的,因为这些属性是5.0以后才加入的。

2. 自定义ATTRS数组,使用obtainStyledAttributes方法得到app:backgroundTint和app:backgroundTintMode的值。

3. 使用v4包中的ViewCompat类----ViewCompat.setBackgroundTintList,ViewCompat.setBackgroundTintMode方法设置tint。

大功告成,这样可以同时兼容4.x和5.x。如果只在java代码中使用,其实只要使用ViewCompat类就好了,其实底层原理是一样的,都是ColorFilter、PorterDuff在起作用,ViewCompact针对不同版本进行了封装,更容易使用了,不用我们去管底层实现细节。

我自己写了个工具类,代码如下

package com.sky.support;

import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by sky on 2015/9/15.
 * <p/>
 * View Utils
 */
public class ViewUtils {

    private static final int[] TINT_ATTRS = {
            R.attr.backgroundTint,      //in v7
            R.attr.backgroundTintMode,  //in v7
    };

    public static void supportTint(View view, AttributeSet attrs) {
        TypedArray a = view.getContext().obtainStyledAttributes(attrs, TINT_ATTRS);
        if (a.hasValue(0)){
            //set backgroundTint
            ColorStateList colorStateList = a.getColorStateList(0);
            ViewCompat.setBackgroundTintList(view, colorStateList);
        }
        if (a.hasValue(1)){
            //set backgroundTintMode
            int mode = a.getInt(1, -1);
            ViewCompat.setBackgroundTintMode(view, parseTintMode(mode, null));
        }
        a.recycle();
    }

    /**
     * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode
     * attribute's enum value.
     *
     * @hide
     */
    public static PorterDuff.Mode parseTintMode(int value, PorterDuff.Mode defaultMode) {
        switch (value) {
            case 3:
                return PorterDuff.Mode.SRC_OVER;
            case 5:
                return PorterDuff.Mode.SRC_IN;
            case 9:
                return PorterDuff.Mode.SRC_ATOP;
            case 14:
                return PorterDuff.Mode.MULTIPLY;
            case 15:
                return PorterDuff.Mode.SCREEN;
            case 16:
                return PorterDuff.Mode.ADD;
            default:
                return defaultMode;
        }
    }
}
原文地址:https://www.cnblogs.com/DarkMaster/p/4811072.html