«

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

时间:2024-3-2 19:59     作者:韩俊     分类: Android


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);

}

}



        <p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>

标签: android

热门推荐