Material设计非得靠Android L吗?看过来,自定View仿elevation效果!

本文介绍了一种使用阴影效果实现Material设计中纸和z轴概念的方法,并提供了代码示例,展示了如何在Android应用中创建类似的效果。

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

Material设计中主要就是纸和z轴的概念,如果根据z值绘制出阴影效果,就基本实现了elevation效果了。

先上个效果图

代码不多,效果却不错,在此抛砖引玉,希望大家开阔思维,做出更多更好效果。

package com.zjg.smart.android.view;

 

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

 

import com.zjg.smart.android.utils.DimensionUtils;

import com.zjg.test.Common;

 

public class ShadowView extends View {

    private Context context = null;

    private float density = 1.0f;

    private int z = 10;

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private int startShadowColor = 0x00999999;

    private int endShadowColor = 0x66999999;

 

    public ShadowView(Context context) {

       this(context, null);

       // TODO自动生成的构造函数存根

    }

 

    public ShadowView(Context context, AttributeSet attrs) {

       this(context, attrs, 0);

       // TODO自动生成的构造函数存根

    }

 

    public ShadowView(Context context, AttributeSet attrs, int defStyle) {

       super(context, attrs, defStyle);

       // TODO自动生成的构造函数存根

       this.context = context;

       density = DimensionUtils.getDensity(context);

    }

 

    protected int getInterpolationColor(int c1, int c2, int ratio) {

       ratio = ratio < 0 ? 0 : ratio;

       ratio = ratio > 255 ? 255 : ratio;

 

       int r1 = Color.red(c1);

       int g1 = Color.green(c1);

       int b1 = Color.blue(c1);

       int a1 = Color.alpha(c1);

 

       int r2 = Color.red(c2);

       int g2 = Color.green(c2);

       int b2 = Color.blue(c2);

       int a2 = Color.alpha(c2);

 

       int r = (r1 * (255 - ratio) + r2 * ratio) >> 8;

       int g = (g1 * (255 - ratio) + g2 * ratio) >> 8;

       int b = (b1 * (255 - ratio) + b2 * ratio) >> 8;

       int a = (a1 * (255 - ratio) + a2 * ratio) >> 8;

 

       return Color.argb(a, r, g, b);

    }

 

    @Override

    protected void onDraw(Canvas canvas) {

       super.onDraw(canvas);

 

       int w = getMeasuredWidth();

       Log.i(Common.LOG_TAG, "w = " + w);

       int h = getMeasuredHeight() - z;

       Log.i(Common.LOG_TAG, "h = " + h);

       int radius = (w < h ? w : h) >> 1;

       Log.i(Common.LOG_TAG, "radius = " + radius);

       float x = radius;

       Log.i(Common.LOG_TAG, "x = " + x);

       float y = radius;

       Log.i(Common.LOG_TAG, "y = " + y);

       // radius -= z;

       Log.i(Common.LOG_TAG, "radius = " + radius);

 

       // 阴影

       int step = 255 / z;

       for (int i = z; i > 0; i--) {

           int shadowColor = getInterpolationColor(startShadowColor,

                  endShadowColor, step * (z - i));

           paint.setColor(shadowColor);

           canvas.drawCircle(x, y + i, radius, paint);

       }

 

       // 设定颜色

       paint.setColor(0xffba68c8);

       canvas.drawCircle(x, y, radius, paint);

    }

 

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

       // TODO自动生成的方法存根

       setMeasuredDimension(measureWidth(widthMeasureSpec),

              measureHeight(heightMeasureSpec));

    }

 

    private int measureWidth(int measureSpec) {

       int result = 0;

       int specMode = MeasureSpec.getMode(measureSpec);

       int specSize = MeasureSpec.getSize(measureSpec);

 

       Log.i(Common.LOG_TAG, "wSpecMode=" +getModeName(specMode));

       Log.i(Common.LOG_TAG, "wSpecSize=" + specSize);

 

       if (specMode == MeasureSpec.EXACTLY) {

           // We were toldhow big to be

           result = specSize;

       } else {

           // Measure thetext

           result = (int) (56 * density);

           Log.i(Common.LOG_TAG, "result=" + result);

           if (specMode == MeasureSpec.AT_MOST) {

              // RespectAT_MOST value if that was what is called for by

              // measureSpec

              result = result < specSize ? result : specSize;

           }

       }

       return result;

    }

 

    private int measureHeight(int measureSpec) {

       int result = 0;

       int specMode = MeasureSpec.getMode(measureSpec);

       int specSize = MeasureSpec.getSize(measureSpec);

 

       Log.i(Common.LOG_TAG, "hSpecMode=" +getModeName(specMode));

       Log.i(Common.LOG_TAG, "hSpecSize=" + specSize);

 

       if (specMode == MeasureSpec.EXACTLY) {

           // We were toldhow big to be

           result = specSize;

       } else {

           // Measure thetext

           result = (int) (56 * density);

           Log.i(Common.LOG_TAG, "result=" + result);

           if (specMode == MeasureSpec.AT_MOST) {

              // RespectAT_MOST value if that was what is called for by

              // measureSpec

              result = result < specSize ? result : specSize;

           }

       }

       return result + z;

    }

 

    private String getModeName(int specMode) {

       // TODO自动生成的方法存根

       if (specMode == MeasureSpec.UNSPECIFIED) {

           return "UNSPECIFIED";

       } else if (specMode == MeasureSpec.EXACTLY) {

           return "EXACTLY";

       } else if (specMode == MeasureSpec.AT_MOST) {

           return "AT_MOST";

       }

       return "";

    }

 

}

 

<?xml version="1.0"encoding="utf-8"?>

<RelativeLayout 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: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=".MyActivity" >

 

    <com.zjg.smart.android.view.ShadowView

       android:layout_width="56dp"

       android:layout_height="56dp"

       android:layout_alignParentBottom="true"

       android:layout_alignParentRight="true"

       android:layout_marginBottom="16dp"

       android:layout_marginRight="16dp"/>

 

</RelativeLayout>



package com.zjg.test;

 

import android.app.Activity;

import android.os.Bundle;

 

public class ShadowViewTest extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_shadow_test);

    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值