Tint 属性

  Tint 是 Android5.0 引入的一个属性,它可以在Android5.0 系统上,对视图进行颜色渲染。 
下面是网上一个使用tint属性给背景调整不同颜色的例子:

 "horizontal"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_gravity="center_horizontal">          ...              android:src="@drawable/xamarin_white"              android:background="@drawable/mycircle"/>          ...              android:src="@drawable/xamarin_white"              android:background="@drawable/mycircle"              android:tint="#2C3E50"/>          ...              android:src="@drawable/xamarin_white"              android:background="@drawable/mycircle"              android:tint="#B4BCBC"/>        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

效果图: 

  tint这个属性,是ImageView有的,它可以给ImageView的src设置,除了tint 之外,还有backgroundTint,foregroundTint,drawableTint,它们分别对应对背景、前景、drawable进行着色处理。 如果,我们给上面的例子设置 backgroundTint,那么蓝色背景就会被着色,替换成你设置的颜色。

原理

  在5.0以上,View类中增加了对tint属性的获取

  case R.styleable.View_backgroundTint:                    // This will get applied later during setBackground().                    if (mBackgroundTint == null) {                        mBackgroundTint = new TintInfo();                    }                    mBackgroundTint.mTintList = a.getColorStateList(                            R.styleable.View_backgroundTint);                    mBackgroundTint.mHasTintList = true;                    break;case R.styleable.View_backgroundTintMode:    // This will get applied later during setBackground().    if (mBackgroundTint == null) {        mBackgroundTint = new TintInfo();    }    mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(            R.styleable.View_backgroundTintMode, -1), null);    mBackgroundTint.mHasTintMode = true;    break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

以具体的 ImageView 为例

//在构造函数中调用了这个方法private void applyImageTint() {        if (mDrawable != null && (mHasDrawableTint || mHasDrawableTintMode)) {            mDrawable = mDrawable.mutate();            if (mHasDrawableTint) {                mDrawable.setTintList(mDrawableTintList);            }            if (mHasDrawableTintMode) {                mDrawable.setTintMode(mDrawableTintMode);            }            // The drawable (or one of its children) may not have been            // stateful before applying the tint, so let's try again.            if (mDrawable.isStateful()) {                mDrawable.setState(getDrawableState());            }        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

setTintList 方法的实现

public void setTintList(ColorStateList tint) {        mBitmapState.mTint = tint;        mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);        invalidateSelf();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

当追踪到 updateTintFilter()这个方法的时候,我们就无法继续向下追踪了,不过研究参数也可以得出它实现的方式(PorterDuffColorFilter,BitmapDrawable.BitmapState,PorterDuff.Mode), 很明显,还是利用的PorterDuff那些相关类来实现的操作,ProterDuff 网上也有很多说明的例子,最重要的还是下图: 有关这些Mode的详细解释,大家自行查阅 

版本问题

Tint在默认只在Android5.0以上的系统生效,为了向下支持,系统提供了相应的Compact类,包括 
AppCompatTextView、AppCompatImageView等。我们使用 ViewCompat.setBackgroundTintMode 在懂吗中动态的为 View 进行tint 操作,观察 这些Compat类发现都实现了 TintableBackgroundView 这个接口,如果需要让自定义的 View实现tint功能,我们可以仿照系统的实现类来实现。

/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.support.v4.view;import android.content.res.ColorStateList;import android.graphics.PorterDuff;import android.support.annotation.Nullable;/** * Interface which allows a {@link android.view.View} to receive background tinting calls from * {@code ViewCompat} when running on API v20 devices or lower. */public interface TintableBackgroundView {    /**     * Applies a tint to the background drawable. Does not modify the current tint     * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.     * 

* Subsequent calls to {@code View.setBackground(Drawable)} will automatically * mutate the drawable and apply the specified tint and tint mode. * * @param tint the tint to apply, may be {@code null} to clear tint * * @see #getSupportBackgroundTintList() */ void setSupportBackgroundTintList(@Nullable ColorStateList tint); /** * Return the tint applied to the background drawable, if specified. * * @return the tint applied to the background drawable */ @Nullable ColorStateList getSupportBackgroundTintList(); /** * Specifies the blending mode used to apply the tint specified by * {@link #setSupportBackgroundTintList(ColorStateList)}} to the background * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}. * * @param tintMode the blending mode used to apply the tint, may be * {@code null} to clear tint * @see #getSupportBackgroundTintMode() */ void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode); /** * Return the blending mode used to apply the tint to the background * drawable, if specified. * * @return the blending mode used to apply the tint to the background * drawable */ @Nullable PorterDuff.Mode getSupportBackgroundTintMode();}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

参考:http://www.open-open.com/lib/view/open1454052058573.html

更多相关文章

  1. android Notification 的使用!!!
  2. Android——常用的系统服务
  3. Android(安卓)系统剪贴板的使用 - 复制、获取和清空
  4. Android系统架构介绍
  5. Android文本输入框EditText方法说明和属性
  6. Android:AndroidManifest.xml
  7. Android(安卓)系统提供媒体库 URI 与 数据库的对应关系
  8. android在ubuntu桌面系统下编译可能的错误和解决方法
  9. Android(安卓)帧动画 补间动画 属性动画 区别

随机推荐

  1. Android Studio 无法预览xml布局视图
  2. [原创]Android(安卓)HAL实例学习-Jollen
  3. Android打包常见问题
  4. 菜鸟的安卓实习之路----editText 只允许
  5. Delphi XE5 Android 调用手机震动
  6. Android x86 4.4-r5 分支修改笔记——系
  7. Android ——对HandlerThread的理解和注
  8. AndroidManifest.xml 详解 (五) 之uses-f
  9. Android 简单的网络变化监听器
  10. Android Studio多个Module依赖同一个jar