视图

首先来讲Material Design 视图的概念,在新的api中,新添加了z轴的概念,z轴垂直于屏幕,用来表现元素的层叠关系,z值(海拔高度)越高,元素离界面底层(水平面)越远,投影越重,这里有一个前提,所有的元素的厚度都是1dp。

Material Design中UI主打扁平化,但是这种扁平化是扁而不平,是对现实的拟物扁平化,所以引入z轴空间的概念,即所有元素都有默认的海拔高度,对它进行操作会抬升它的海拔高度,操作结束后,它应该落回默认海拔高度。同一种元素,同样的操作,抬升的高度是一致的。

既然加入z轴,那么这种空间感是怎么体现出来的呢?答案就是View的elevation(阴影高度),细心的可以发现在Android 5.0后所有控件中都多了这么两个属性:elevation、translationZ。分别表示阴影的大小和往z轴平移的大小(用作动画效果)。不过这两个属性只在api 21(5.0)以上才有效果。在z轴上有这么一个关系:

Z = elevation + translationZ

我们可以在layout中或者在代码中使用它们:

android:elevation

View.setElevation()

Tint详解

在Android 5.0后,引入了一个叫tint的属性,意思叫“着色”,有两种形式:

1、android:backgroundTint=””

2、android:tint=”“

细心的同学就会发现,在给一些控件(Button、EditText等)设置背景时候可以看到新添加了backgroundTint属性:



而在给ImageView设置时候,则添加了tint和backgroundTint属性:

同时,还分别新增了与之对应的TintMode属性,表示tint的模式:

那么,既然有了background可以设置背景色还加入Tint干嘛呢?Tint是用来是干什么的呢?

首先我们得了解这两个属性的用处:

了解之前我们先了解TintMode

顾名思义,TintMode是改变我们着色的模式。

Mode的取值有六种:

1、add -

2、screen -

3、src_over -

4、src_in -

5、multiply -

6、src_atop -

关于它们的特性请看传送门:PorterDuff.Mode

一般情况下默认是src_in。

1、backgroundTint - 当然是着背景色了

那么我们就来使用它试试效果,我们给Button着上红色的背景色:

<Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/red"
        android:text="Button2" />

效果:



我们发现这背景色并没有改变,为什么呢?既然tint是给背景色着色,那么肯定是需要有背景色的前提下,我们给Button随便加上一个背景颜色后:

<Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/red"
        android:background="#ffffff"
        android:text="Button2" />

效果:



可以发现,tint的作用的却是给当前控件的背景色着上一个我们指定的颜色。

每个模式不同的效果想看的自己实现,这里就不贴了,因为重点是下面对ImageView的遮罩进行着色。

2、tint - 则是给图片着上一层遮罩颜色

废话不多说,贴一张效果图自然明白了,我们给图片罩上一层红色的遮罩后,不同模式显示的效果:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg" />

        <Space
            android:layout_width="30dp"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red" />

        <Space
            android:layout_width="30dp"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="add" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="src_atop" />

        <Space
            android:layout_width="30dp"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="src_over" />

        <Space
            android:layout_width="30dp"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="multiply" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="screen" />

        <Space
            android:layout_width="30dp"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/bg"
            android:tint="@color/red"
            android:tintMode="src_in" />
    </LinearLayout>
</LinearLayout>

Tint兼容性

上述效果均是在Android 5.0以上的平台上才支持,不过,如果我们想支持5.0以下的,我们可以使用support-v7包下的AppCompat**** 控件,不过我们还是不能在layout中使用它,只能通过代码

ViewCompat.setSupportBackgroundTintList(ColorStateList tint);
ViewCompat.setSupportBackgroundTintMode(PorterDuff.Mode tintMode);

来设置。setSupportBackgroundTintList()方法接收的是一个ColorStateList类型的参数,我们可以通过

ColorStateList lists = getResources().getColorStateList(R.color.red);

得到对应颜色的ColorStateList对象,并设置给它。

如,下面我使用AppCompat控件并着色:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Button" />

    <Space
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/edt"
        android:layout_width="match_parent"
        android:layout_height="50dp" />
</LinearLayout>

代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AppCompatButton mBtnCompat = (AppCompatButton) findViewById(R.id.btn1);
        ColorStateList lists = getResources().getColorStateList(R.color.red);
        mBtnCompat.setSupportBackgroundTintList(lists);
        mBtnCompat.setSupportBackgroundTintMode(PorterDuff.Mode.SRC_IN);

        ColorStateList lists2 = getResources().getColorStateList(R.color.bule);
        AppCompatEditText mEdt = (AppCompatEditText) findViewById(R.id.edt);
        mEdt.setSupportBackgroundTintList(lists2);
    }

其实AppCompatEditText中底下那根线是一张黑色的.9线条图片,AppCompatButton也是通过一张.9图片进行着色的,所以我们通过backgroundTint能让它着成不同的颜色。

效果:

所以,综上的效果,backgroundTint和android:tint属性可以帮我们在原图只有一张的情况下,我们利用tint可以轻松的把图片换成我们需要的颜色,这极大减小了apk因包含众多图片的大小。

让自定义控件加上对Tint支持

在5.0以下,我们对自定义的控件也加上对tint的支持:

public class AppCompatCustomView extends View implements TintableBackgroundView {

    private static final int[] TINT_ATTRS = {
            android.R.attr.background
    };

    private TintInfo mInternalBackgroundTint;
    private TintInfo mBackgroundTint;
    private TintManager mTintManager;

    public AppCompatCustomView(Context context) {
        this(context, null);
    }

    public AppCompatCustomView(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public AppCompatCustomView(Context context, AttributeSet attributeSet, int defStyle) {
        super(context, attributeSet, defStyle);

        if (TintManager.SHOULD_BE_USED) {
            TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attributeSet,
                    TINT_ATTRS, defStyle, 0);
            if (a.hasValue(0)) {
                ColorStateList tint = a.getTintManager().getTintList(a.getResourceId(0, -1));
                if (tint != null) {
                    setInternalBackgroundTint(tint);
                }
            }
            mTintManager = a.getTintManager();
            a.recycle();
        }
    }

    private void applySupportBackgroundTint() {
        if (getBackground() != null) {
            if (mBackgroundTint != null) {
                TintManager.tintViewBackground(this, mBackgroundTint);
            } else if (mInternalBackgroundTint != null) {
                TintManager.tintViewBackground(this, mInternalBackgroundTint);
            }
        }
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        applySupportBackgroundTint();
    }

    private void setInternalBackgroundTint(ColorStateList tint) {
        if (tint != null) {
            if (mInternalBackgroundTint == null) {
                mInternalBackgroundTint = new TintInfo();
            }
            mInternalBackgroundTint.mTintList = tint;
            mInternalBackgroundTint.mHasTintList = true;
        } else {
            mInternalBackgroundTint = null;
        }
        applySupportBackgroundTint();
    }

    @Override
    public void setSupportBackgroundTintList(ColorStateList tint) {
        if (mBackgroundTint == null) {
            mBackgroundTint = new TintInfo();
        }
        mBackgroundTint.mTintList = tint;
        mBackgroundTint.mHasTintList = true;

        applySupportBackgroundTint();
    }

    @Nullable
    @Override
    public ColorStateList getSupportBackgroundTintList() {
        return mBackgroundTint != null ? mBackgroundTint.mTintList : null;
    }

    @Override
    public void setSupportBackgroundTintMode(PorterDuff.Mode tintMode) {
        if (mBackgroundTint == null) {
            mBackgroundTint = new TintInfo();
        }
        mBackgroundTint.mTintMode = tintMode;
        mBackgroundTint.mHasTintMode = true;

        applySupportBackgroundTint();
    }

    @Nullable
    @Override
    public PorterDuff.Mode getSupportBackgroundTintMode() {
        return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
    }
}

使用Material Design Tint和视图详解的更多相关文章

  1. Android Material Design 系列之 SnackBar详解

    SnackBar是google Material Design提供的一种轻量级反馈组件.支持从布局的底部显示一个简洁的提示信息,支持手动滑动取消操作,同时在同一个时间内只能显示一个SnackBar. ...

  2. Android Design Support Library使用详解

    Android Design Support Library使用详解 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的And ...

  3. ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解

    原文 ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 ...

  4. 【译】ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解

    原文:[译]ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解 在本节中,我们继续研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打 ...

  5. [转]PostgreSQL教程(十六):系统视图详解

    这篇文章主要介绍了PostgreSQL教程(十六):系统视图详解,本文讲解了pg_tables.pg_indexes.pg_views.pg_user.pg_roles.pg_rules.pg_set ...

  6. (转)oracle视图详解

    Oracle视图详解   一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的.视图只有逻辑定义.每次使用的时候,只是重新执 ...

  7. calcite物化视图详解

    概述 物化视图和视图类似,反映的是某个查询的结果,但是和视图仅保存SQL定义不同,物化视图本身会存储数据,因此是物化了的视图. 当用户查询的时候,原先创建的物化视图会注册到优化器中,用户的查询命中物化 ...

  8. Android Design Support Library使用详解——TextInputLayout与TextInputEditText

    TextInputLayout 在谷歌的Material Design中,文本输入是这样表现的:当用户点击输入框想要输入文字时,如果输入框是空的,那么它的提示文字(hint)就会变小并且同时移动到输入 ...

  9. Android Design Support Library使用详解——Snackbar

    Google在2015 I/O大会上,给我们带来了更加详细的Material Design规范,同时也引入了Android Design Support Library,为我们提供了基于Materia ...

随机推荐

  1. 1.Cocos2dx 3.2中vector,ValueMap,Touch触摸时间的使用.iconv字符编解码

     Cocos2dx3.2以后使用Vector<T>代替了CCArray.案例如下: 头文件:T02Vector.h #ifndef __T02Vector_H__ #define __ ...

  2. Hibernate实体映射文件多对多等关系简单应用技巧

    认真开完以后,就能很简单的写出各种关系了 第一步,写注释: <!--xx属性,本类与Yy(类)的多对一 --> <!--xx属性,本类与Yy(类)的一对多 --> <!- ...

  3. HDFS的读数据过程分析

    我们继续在 FileSystem 类分析,读数据使用的是 open(-)方法,我们可以看到源码 FSDataInputStream in = fileSystem.open(new Path(&quo ...

  4. Objc中为何某些类的属性要设置为copy而不是strong?

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 不知道大家是否注意,我们再使用一些第三方类的时候大多数情况下对 ...

  5. Android的ToggleButton和Switch以及AnalogColok和DigitalColok的用法-android学习之旅(二十)

    ToggleButton 和Switch简介 ToggleButton 和Switch都是继承了Button,所以他们的属性设置和Button差不多. 分别支持的属性 ToggleButton 的属性 ...

  6. iOS中 最新微信支付/最全的微信支付教程详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 亲们, 首先让我们来看一下微信支付的流程吧. 1. 注册微信开放平台,创建应用获取appid,appSecret, ...

  7. 人类创造未来的思想先锋:这些 TED 演示深深震撼着我们

    今年亮点之一是谷歌创始人拉里佩奇的演讲.他有一个核心观点:特别成功的公司,是那些敢于想象未来,并付出行动创造未来的公司.这听上去是老生常谈,但又确实是个真理.他实际上想说预测未来的最好方式就是创造它, ...

  8. JQuery EasyUI combobox(下拉列表框)

     下拉列表框 继承 $.fn.combo.defaults. 重写 $.fn.combobox.defaults. 组合框显示一个可编辑的文本框和下拉列表,用户选择一个或多个值.用户可以直接输入文 ...

  9. CUDA command Profiler

    这里我不使用默认设置: timestamp gpustarttimestamp gpuendtimestamp gridsize threadblocksize dynsmemperblock sta ...

  10. 《重构》中Tips总结

    1         如果你发现自己需要为程序添加一个特性,而代码结构使你无法很方便地达到目的,那就先重构那个程序,使特性的添加比较容易进行,然后再添加特性. 2         重构之前,首先检查自己 ...