Material设计非得靠Android L吗?看过来,自定View仿elevation效果!
2015-06-25 22:53
393 查看
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);
}
}
先上个效果图
代码不多,效果却不错,在此抛砖引玉,希望大家开阔思维,做出更多更好效果。
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);
}
}
相关文章推荐
- Android应用实例之有道辞典
- Android中fragment切换状态
- 在ubuntu上搭建android开发环境(1)——安装ubuntu
- android项目的目录结构
- Activity回传值实例
- 菜鸟学Android笔记(四十二):Include指令及九大隐式对象
- Android基础组件(一)自动完成控件AutoCompleteTextView
- Android 应用四大组件
- ProgressDialog show()的时候 12-18 11:05:55.356: E/AndroidRuntime(461): android.view.WindowManager$Ba
- Worklight生成的android代码, 运行时,
- Android Studio内存优化
- Android存储数据的5种方式
- Android greenDAO入门
- Activity嵌套多个Fragment实现横竖屏切换
- SlidingMenu属性详解【Android】
- 6.Android工程更改api版本?
- 当android API导入的是较低版本,如2.3.3. 但仍提示AVD API低?
- 【进阶android】ListView源码分析——布局三大方法
- 【Android】SlidingMenu属性详解
- android EditText输入变化事件详解