Android 5.0学习之定义阴影

前言

Material Design 规范指导里面特别提出了阴影的重要性和如何正确使用的方法(点击传送),那我们就更加不能忽视这一点了,本篇文章就要教大家如何设置阴影,做出一个有层次感的界面。

设置方法:
android:elevation
分别设置不同数值的elevation效果如下:

layout:
[html] view plain copy print ?
  1. <LinearLayout  
  2.          android:layout_width="match_parent"  
  3.          android:layout_height="wrap_content"  
  4.          android:orientation="horizontal">  
  5.      <TextView android:layout_width="100dp"  
  6.                android:layout_margin="2dp"  
  7.                android:layout_height="100dp"  
  8.                android:text="test"  
  9.                android:background="@android:color/white"  
  10.                android:gravity="center"  
  11.                android:elevation="1dip"  
  12.              />  
  13.      <TextView android:layout_width="100dp"  
  14.                android:layout_margin="2dp"  
  15.                android:layout_height="100dp"  
  16.                android:text="test"  
  17.                android:background="@android:color/white"  
  18.                android:gravity="center"  
  19.                android:elevation="4dip"/>  
  20.      <TextView android:layout_width="100dp"  
  21.                android:layout_margin="2dp"  
  22.                android:layout_height="100dp"  
  23.                android:text="test"  
  24.                android:background="@android:color/white"  
  25.                android:gravity="center"  
  26.                android:elevation="8dip"  
  27.              />  
  28.  LinearLayout>  

View的z值由两部分组成,elevation和translationZ.

eleavation是静态的成员,translationZ是用来做动画。

Z = elevation + translationZ


在布局中使用 android:elevation属性去定义 

在代码中使用 View.setElevation 方法去定义 

设置视图的translation,可以使用View.setTranslationZ方法 

新的ViewPropertyAnimator.zViewPropertyAnimator.translationZ方法可以设置视图的elevation


在5.0 的API Demos中 Graphics-》Shadow Card Drag 和 Shadow Card stack 这两个例子就很好的使用translationZ和eleavation


Shadow Card Drag 源码:
[java] view plain copy print ?
  1. /* 
  2.  * Copyright (C) 2014 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.example.android.apis.graphics;  
  18.   
  19. import android.animation.ObjectAnimator;  
  20. import android.app.Activity;  
  21. import android.graphics.Canvas;  
  22. import android.graphics.Color;  
  23. import android.graphics.Outline;  
  24. import android.graphics.Paint;  
  25. import android.graphics.Path;  
  26. import android.graphics.PorterDuff;  
  27. import android.graphics.drawable.ShapeDrawable;  
  28. import android.graphics.drawable.shapes.OvalShape;  
  29. import android.graphics.drawable.shapes.RectShape;  
  30. import android.graphics.drawable.shapes.RoundRectShape;  
  31. import android.graphics.drawable.shapes.Shape;  
  32. import android.os.Bundle;  
  33. import android.view.MotionEvent;  
  34. import android.view.View;  
  35. import android.view.animation.AccelerateInterpolator;  
  36. import android.view.animation.DecelerateInterpolator;  
  37. import android.widget.Button;  
  38. import android.widget.CheckBox;  
  39. import android.widget.CompoundButton;  
  40. import com.example.android.apis.R;  
  41.   
  42. import java.util.ArrayList;  
  43.   
  44. public class ShadowCardDrag extends Activity {  
  45.     private static final float MAX_Z_DP = 10;  
  46.     private static final float MOMENTUM_SCALE = 10;  
  47.     private static final int MAX_ANGLE = 10;  
  48.   
  49.     private class CardDragState {  
  50.         long lastEventTime;  
  51.         float lastX;  
  52.         float lastY;  
  53.   
  54.         float momentumX;  
  55.         float momentumY;  
  56.   
  57.         public void onDown(long eventTime, float x, float y) {  
  58.             lastEventTime = eventTime;  
  59.             lastX = x;  
  60.             lastY = y;  
  61.   
  62.             momentumX = 0;  
  63.             momentumY = 0;  
  64.         }  
  65.   
  66.         public void onMove(long eventTime, float x, float y) {  
  67.             final long deltaT = eventTime - lastEventTime;  
  68.   
  69.             if (deltaT != 0) {  
  70.                 float newMomentumX = (x - lastX) / (mDensity * deltaT);  
  71.                 float newMomentumY = (y - lastY) / (mDensity * deltaT);  
  72.   
  73.                 momentumX = 0.9f * momentumX + 0.1f * (newMomentumX * MOMENTUM_SCALE);  
  74.                 momentumY = 0.9f * momentumY + 0.1f * (newMomentumY * MOMENTUM_SCALE);  
  75.   
  76.                 momentumX = Math.max(Math.min((momentumX), MAX_ANGLE), -MAX_ANGLE);  
  77.                 momentumY = Math.max(Math.min((momentumY), MAX_ANGLE), -MAX_ANGLE);  
  78.   
  79.                 //noinspection SuspiciousNameCombination  
  80.                 mCard.setRotationX(-momentumY);  
  81.                 //noinspection SuspiciousNameCombination  
  82.                 mCard.setRotationY(momentumX);  
  83.   
  84.                 if (mShadingEnabled) {  
  85.                     float alphaDarkening = (momentumX * momentumX + momentumY * momentumY) / (90 * 90);  
  86.                     alphaDarkening /= 2;  
  87.   
  88.                     int alphaByte = 0xff - ((int)(alphaDarkening * 255) & 0xff);  
  89.                     int color = Color.rgb(alphaByte, alphaByte, alphaByte);  
  90.                     mCardBackground.setColorFilter(color, PorterDuff.Mode.MULTIPLY);  
  91.                 }  
  92.             }  
  93.   
  94.             lastX = x;  
  95.             lastY = y;  
  96.             lastEventTime = eventTime;  
  97.         }  
  98.   
  99.         public void onUp() {  
  100.             ObjectAnimator flattenX = ObjectAnimator.ofFloat(mCard, "rotationX"0);  
  101.             flattenX.setDuration(100);  
  102.             flattenX.setInterpolator(new AccelerateInterpolator());  
  103.             flattenX.start();  
  104.   
  105.             ObjectAnimator flattenY = ObjectAnimator.ofFloat(mCard, "rotationY"0);  
  106.             flattenY.setDuration(100);  
  107.             flattenY.setInterpolator(new AccelerateInterpolator());  
  108.             flattenY.start();  
  109.             mCardBackground.setColorFilter(null);  
  110.         }  
  111.     }  
  112.   
  113.     /** 
  114.      * Simple shape example that generates a shadow casting outline. 
  115.      */  
  116.     private static class TriangleShape extends Shape {  
  117.         private final Path mPath = new Path();  
  118.   
  119.         @Override  
  120.         protected void onResize(float width, float height) {  
  121.             mPath.reset();  
  122.             mPath.moveTo(00);  
  123.             mPath.lineTo(width, 0);  
  124.             mPath.lineTo(width / 2, height);  
  125.             mPath.lineTo(00);  
  126.             mPath.close();  
  127.         }  
  128.   
  129.         @Override  
  130.         public void draw(Canvas canvas, Paint paint) {  
  131.             canvas.drawPath(mPath, paint);  
  132.         }  
  133.   
  134.         @Override  
  135.         public void getOutline(Outline outline) {  
  136.             outline.setConvexPath(mPath);  
  137.         }  
  138.     }  
  139.   
  140.     private final ShapeDrawable mCardBackground = new ShapeDrawable();  
  141.     private final ArrayList mShapes = new ArrayList();  
  142.     private float mDensity;  
  143.     private View mCard;  
  144.   
  145.     private final CardDragState mDragState = new CardDragState();  
  146.     private boolean mTiltEnabled;  
  147.     private boolean mShadingEnabled;  
  148.   
  149.     @Override  
  150.     protected void onCreate(Bundle savedInstanceState) {  
  151.         super.onCreate(savedInstanceState);  
  152.         setContentView(R.layout.shadow_card_drag);  
  153.   
  154.         mDensity = getResources().getDisplayMetrics().density;  
  155.         mShapes.add(new RectShape());  
  156.         mShapes.add(new OvalShape());  
  157.         float r = 10 * mDensity;  
  158.         float radii[] = new float[] {r, r, r, r, r, r, r, r};  
  159.         mShapes.add(new RoundRectShape(radii, nullnull));  
  160.         mShapes.add(new TriangleShape());  
  161.   
  162.         mCardBackground.getPaint().setColor(Color.WHITE);  
  163.         mCardBackground.setShape(mShapes.get(0));  
  164.         final View cardParent = findViewById(R.id.card_parent);  
  165.         mCard = findViewById(R.id.card);  
  166.         mCard.setBackground(mCardBackground);  
  167.   
  168.         final CheckBox tiltCheck = (CheckBox) findViewById(R.id.tilt_check);  
  169.         tiltCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
  170.             @Override  
  171.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  172.                 mTiltEnabled = isChecked;  
  173.                 if (!mTiltEnabled) {  
  174.                     mDragState.onUp();  
  175.                 }  
  176.             }  
  177.         });  
  178.   
  179.         final CheckBox shadingCheck = (CheckBox) findViewById(R.id.shading_check);  
  180.         shadingCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
  181.             @Override  
  182.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  183.                 mShadingEnabled = isChecked;  
  184.                 if (!mShadingEnabled) {  
  185.                     mCardBackground.setColorFilter(null);  
  186.                 }  
  187.             }  
  188.         });  
  189.   
  190.         final Button shapeButton = (Button) findViewById(R.id.shape_select);  
  191.         shapeButton.setOnClickListener(new View.OnClickListener() {  
  192.             int index = 0;  
  193.             @Override  
  194.             public void onClick(View v) {  
  195.                 index = (index + 1) % mShapes.size();  
  196.                 mCardBackground.setShape(mShapes.get(index));  
  197.             }  
  198.         });  
  199.   
  200.         /** 
  201.          * Enable any touch on the parent to drag the card. Note that this doesn't do a proper hit 
  202.          * test, so any drag (including off of the card) will work. 
  203.          * 
  204.          * This enables the user to see the effect more clearly for the purpose of this demo. 
  205.          */  
  206.         cardParent.setOnTouchListener(new View.OnTouchListener() {  
  207.             float downX;  
  208.             float downY;  
  209.             long downTime;  
  210.   
  211.             @Override  
  212.             public boolean onTouch(View v, MotionEvent event) {  
  213.                 switch (event.getAction()) {  
  214.                     case MotionEvent.ACTION_DOWN:  
  215.                         downX = event.getX() - mCard.getTranslationX();  
  216.                         downY = event.getY() - mCard.getTranslationY();  
  217.                         downTime = event.getDownTime();  
  218.                         ObjectAnimator upAnim = ObjectAnimator.ofFloat(mCard, "translationZ",  
  219.                                 MAX_Z_DP * mDensity);  
  220.                         upAnim.setDuration(100);  
  221.                         upAnim.setInterpolator(new DecelerateInterpolator());  
  222.                         upAnim.start();  
  223.                         if (mTiltEnabled) {  
  224.                             mDragState.onDown(event.getDownTime(), event.getX(), event.getY());  
  225.                         }  
  226.                         break;  
  227.                     case MotionEvent.ACTION_MOVE:  
  228.                         mCard.setTranslationX(event.getX() - downX);  
  229.                         mCard.setTranslationY(event.getY() - downY);  
  230.                         if (mTiltEnabled) {  
  231.                             mDragState.onMove(event.getEventTime(), event.getX(), event.getY());  
  232.                         }  
  233.                         break;  
  234.                     case MotionEvent.ACTION_UP:  
  235.                         ObjectAnimator downAnim = ObjectAnimator.ofFloat(mCard, "translationZ"0);  
  236.                         downAnim.setDuration(100);  
  237.                         downAnim.setInterpolator(new AccelerateInterpolator());  
  238.                         downAnim.start();  
  239.                         if (mTiltEnabled) {  
  240.                             mDragState.onUp();  
  241.                         }  
  242.                         break;  
  243.                 }  
  244.                 return true;  
  245.             }  
  246.         });  
  247.     }  
  248. }  
layout:
[html] view plain copy print ?
  1. xml version="1.0" encoding="utf-8"?>  

你可能感兴趣的:(Android 5.0学习之定义阴影)