Recently the project requirements, UI has a lot of design requirements about shadow, the Internet found some implementation methods, but not very ideal. Now down, thinking about their own writing a shadow layout play, in order to prepare after use. Here are a few ways I’ve found to implement shadows:

Shadow system

Elevation: Elevation: the height of the z-axis elevation :elevation: the height of the z-axis elevation :elevation: the height of the z-axis elevation: the height of the z-axis elevation :elevation: the height of the z-axis elevation: the height of the z-axis elevation:

<! -- base z depth of the view. -->
  <attr name="elevation" format="dimension" />

  <TextView
        android:id="@+id/shadow1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:text="System shadow"
        android:background="#fff"
        android:gravity="center"
        android:textSize="14sp"
        android:textColor="@color/colorBlack"
        android:layout_width="100dp"
        android:elevation="3dp"
        android:layout_height="80dp"/
Copy the code

The effect is also good, can complete some simple shadow Settings effect.

But you need to pay attention to a few details, or an elevation might not work:

  • An elevation does not occupy the size of a view
  • The background color needs to be set and cannot be set to transparent
  • You cannot set whether it is diffuse or directional

False shadow layer – the list

Layer-list itself is very powerful, and the layered drawing supported by layer-list can basically solve most of the background design we said. It is not impossible to use it for some shadows that are not very strict, but the effect is really bad. After all, Shape does not support fuzzy drawing (or you can choose to use a fuzzy background image). Here is a layer-list shadow for reference.

<TextView
    android:id="@+id/shadow2"
    app:layout_constraintStart_toEndOf="@id/shadow1"
    app:layout_constraintTop_toTopOf="parent"
    android:layout_marginStart="50dp"
    android:layout_marginTop="20dp"
    android:text="Layer - the list shadow"
    android:gravity="center"
    android:background="@drawable/shadow_layer"
    android:textSize="14sp"
    android:textColor="@color/colorBlack"
    android:layout_width="100dp"
    android:layout_height="80dp"/>



<! --shadow_layer.xml -->
<?xml version="1.0" encoding="utf-8"? >
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:top="3dp"
        android:left="3dp">
        <shape android:shape="rectangle">
            <solid android:color="# 333333"/>
            <gradient android:startColor="#80ff0000"
                android:type="radial"
                android:centerX="0.5"
                android:centerY="0.5"
                android:gradientRadius="30"
                android:endColor="#10ff0000"/>
            <size android:width="100dp" android:height="80dp"/>
        </shape>
    </item>

    <item android:bottom="3dp"
        android:right="3dp">
        <shape android:shape="rectangle">
            <solid android:color="#fff"/>
            <size android:width="100dp" android:height="80dp"/>
        </shape>
    </item>

</layer-list>

Copy the code

The effect is rather stiff, which is essentially a gradient of color, as follows:

There are also such as let UI cut shadow background map, but due to the control size specification difference, style difference is large, not recommended.

Custom shadow layout

This is my preferred approach, which is to customize a shadow layout implementation by referring to the Shadow implementation of CardView. Its implementation is through setShadowLayer, setMaskFilter implementation.

/ / mPaint. SetShadowLayer (blurRadius, 0, 0, shadowColor);
        if (blurRadius>0){
            mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL));
        }
Copy the code

Compared to setShadowLayer, setMaskFilter has one more blur implementation type, which is better, so I use setMaskFilter to implement the custom shadow layout.

<cn.enjoytoday.shadow.ShadowLayout android:id="@+id/shadow3" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/shadow1" android:layout_marginTop="20dp" android:text="" app:shadowRadius="0dp"  app:shadowColor="#333" app:blurRadius="5dp" app:xOffset="0dp" app:yOffset="0dp" android:layout_marginStart="15dp" android:gravity="center" android:background="@drawable/shadow_layer" android:textSize="14sp" android:textColor="@color/colorBlack" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView Android :padding="5dp" Android :text=" custom app layout" android:textColor="@color/colorBlack" android:layout_width="100dp" android:layout_height="80dp"/> </cn.enjoytoday.shadow.ShadowLayout>Copy the code

use

ShadowView is hosted on GitHub and is designed to mimic the Shadow effect of Box Shadow of CSS. You can set horizontal and vertical offset to confirm the Shadow direction, blur radius and rounded radius, Shadow color, etc. Gradle dependencies can be used directly:

Add the dependent

repositories {
	/ /...
	maven { url 'https://jitpack.io'}}dependencies {
    implementation 'com. Making. Amikoj: ShadowView: 1.0.1'
}

Copy the code

XML is used in


   <cn.enjoytoday.shadow.ShadowLayout
        android:orientation="vertical"
        android:id="@+id/shadowLayout"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="center"
        app:shadowRadius="10dp"
        app:shadowColor="#bebebe"
        app:bgColor="#fff"
        app:xOffset="10dp"
        app:yOffset="0dp"
        app:blurRadius="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

   <! -- Nesting the layout that needs to be shaded -->

    </cn.enjoytoday.shadow.ShadowLayout>
Copy the code

Attributes that

The property name type instructions
shadowColor color Shadow render color
shadowRadius dimension Background fillet radius (0 is rectangle)
blurRadius dimension Fuzzy radius
xOffset dimension Horizontal displacement
yOffset dimension The vertical displacement
bgColor color The background color

Code sets

You can also set the shadow properties with code:

shadowLayout.getShadowConfig()   // Get the configuration class
            . setBlurRadius(blurRadius)  // Set the blur radius
             .setXOffset(xoffset)   // Set the horizontal displacement to 20dp
             .setYOffset(yoffset)   // Set the vertical displacement to 20dp
             .setShadowRadius(shadowRadius) // Set the radius to 0
             .setShadowColor(shadowColor)    // Set the shadow color
             .commit();             // Take effect
Copy the code