Material Design —— Elevation高度、shadows阴影、clipping裁剪、tint着色

本文介绍了Android Material Design中的Elevation(高度)、Shadows(阴影)及其与Outline(轮廓)的关系,阐述了如何通过`android:outlineProvider`属性自定义轮廓,探讨了Clipping(裁剪)视图的概念,以及讲解了Tint(着色)的应用和模式选择。通过示例代码展示了如何设置和调整这些效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Elevation

Android5.0加入了Z轴,这个Z轴的值就是View的高度Elevation

  • elevation的值较大的View会遮盖住较小的

这里写图片描述

code:

<AbsoluteLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <FrameLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#000"
        android:elevation="10dp">
    </FrameLayout>

    <FrameLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_x="50dp"
        android:layout_y="50dp"
        android:background="#CCC"
        android:elevation="5dp">
    </FrameLayout>

</AbsoluteLayout>

效果如下:
这里写图片描述

当然任何控件都会有默认的elevation高度:
这里写图片描述

Shadows阴影和Outline轮廓

  • 轮廓outline代表图形对象的形状
  • 轮廓outline决定阴影的形状
  • 轮廓outline定义触摸反馈的波纹区域。
  • 默认的轮廓为背景可绘制对象,即background
  • shadows阴影的大小是由elevation高度决定的,高度越大,阴影面积越大

自定义轮廓为圆角矩形:

<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>
<FrameLayout
   android:layout_width="100dp"
   android:layout_height="100dp"
   android:background="@drawable/myrect"
   android:elevation="5dp">
</FrameLayout>

在Java中设置轮廓:

ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {  
    @Override  
    public void getOutline(View view, Outline outline) {  
        int size = getResources().getDimensionPixelSize(R.dimen.fab_size);  
        outline.setOval(0, 0, size, size);  
    }  
};  
fab.setOutlineProvider(viewOutlineProvider);  

阴影

阴影的设置也很简单,只要给一个elevation高度,view就拥有阴影了。
为什么是elevation决定阴影的面积呢?
如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <FrameLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:elevation="20dp"
        android:outlineProvider="bounds">
    </FrameLayout>
</LinearLayout>

我们将这个Fragment的高度设置为20dp:
这里写图片描述
100dp:
这里写图片描述

这样就很清楚了,所谓的阴影,是因为我们从上方垂直观察直立的物体产生的。
就像我们从高空俯视大楼。

android:outlineProvider属性

这个属性顾名思义:outline 轮廓的提供者,他有以下几个属性:

  • none 没有轮廓,即没有阴影
  • background,由background提供轮廓,默认是这个选项,如果没有设置background,则不会产生阴影
  • bounds,paddedBounds 由View的默认矩形边界作为outline,在layout编辑预览中可以看到
  • bounds,和 paddedBounds的区别在于:

    <ImageView
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:padding="10dp"
        android:elevation="20dp"
        android:outlineProvider="paddedBounds"
        android:src="@mipmap/ic_launcher"/>
    
    <ImageView
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:padding="10dp"
        android:elevation="20dp"
        android:outlineProvider="bounds"
        android:src="@mipmap/ic_launcher"/>

    这里写图片描述

    前者阴影会填充设置的padding
    后者则不会
    ps:这两个属性的区别折腾我老久了T-T

根据轮廓Clipping裁剪视图

裁剪操作非常耗时,不要加入动画

int margin = Math.min(clippedView.getWidth(), clippedView.getHeight()) / 10;  
Outline mClip = new Outline();  
mClip.setRoundRect(margin, margin, clippedView.getWidth() - margin,  
        clippedView.getHeight() - margin, margin / 2);  
/* Sets the Outline of the View. */  
clippedView.setOutline(mClip);  
/* Enables clipping on the View. */  
clippedView.setClipToOutline(true);  

着色Tint

Material Design 着色是一个很有意思的接口:
使用着色很简单,使用tint指定着色的色彩,使用tintmode指定着色的模式:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"/>

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"
            android:tintMode="screen"/>

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"
            android:tintMode="add"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"
            android:tintMode="src_atop"/>

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"
            android:tintMode="src_in"/>

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            android:src="@mipmap/ic_launcher"
            android:tint="@color/colorPrimary"
            android:tintMode="src_over"/>
    </LinearLayout>

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值