视图

首先来讲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. EBS开发性能优化之SQL语句优化

    (1)选择运算 尽可能先做选择运算,这是优化策略中最重要.最基本的一条,选择运算一般会使计算的中间结果大大变小,在对同一表格进行多个选择运算时,选择条件的排列顺序对性能也有很大影响,因为排列顺序不仅影 ...

  2. iOS界面不能点击(tableView 的cell 不能使用点击事件,tableView也不能上下滚动)

    iOS开发中间遇到了很多问题,有些后来又遇到,竟然忘记怎么处理了,所以还是来写下博客记录自己遇到的问题,方便自己也方便别人. 之前想的是项目小,就用storyboard在绘制界面,但是项目慢慢的扩展, ...

  3. SVN与eclipse整合与使用、SVN与Apache整合

    SVN与eclipse整合 下载SVN插件(http://subclipse.tigris.org) http://subclipse.tigris.org/servlets/ProjectDocum ...

  4. Dynamics CRM 插件注册时报Assembly must be registered in isolation的解决方法

    在插件注册的时候经常会遇到"Assembly must be registered in isolation"的问题导致无法注册,之前经常会被同事或者朋友问到这个问题,遇到这个问题 ...

  5. 6、Android Content Provider测试

    如果你的应用中使用了Content Provider来与其他应用进行数据交互,你需要对Content Provider进行测试来确保正常工作. 创建Content Provider整合测试 在Andr ...

  6. 后端分布式系列:分布式存储-HDFS 架构解析

    本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...

  7. Android的ImageSwitcher和TextSw-android学习之旅(三十四)

    ImageSwitcher简介 ImageSwitcher继承了ViewSwitcher,所以在切换时候会有动画,可以把它理解成一个动画版本的ImageView. 他的showNext(),和show ...

  8. 当freemarker中EL表达式的值为空时出现异常的解决方法

     <#list pageView.list as msg>      <form name="msgForm" id="msgForm" ...

  9. oracle ORA-00917: missing comma 是因为少逗号

    oracle ORA-00917: missing comma 是因为少逗号,而且不是网上盛传的空格问题!都是传言误人啊

  10. 【一天一道LeetCode】#90. Subsets II

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...