首页 > 代码库 > 安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape
安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape
第一篇博客中,我已经对常用的一些方法做了汇总,这篇文章主要介绍BitmapShader位图渲染、ComposeShader组合渲染,然后看看Xfermode如何实际应用。不过本文还是只重写onDraw一个方法,工欲善其事必先利其器嘛,一个方法一个方法地学,先了解每个对象是干什么的。
ViewHelper(View处理常用方法封装)
安卓自定义控件(一)Canvas、Paint、Shader
安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape
带边框的椭圆形ImageView
先写一个自定义控件,鼓励一下自己。
/**
* ShapeDrawable对象的使用
* Created by ChenSS on 2016/11/24.
*/
public class RectView extends View {
private BitmapShader mBitmapShader;
private ShapeDrawable mShapeDrawable;
private Bitmap mBitmap;
private Paint mPaint;
private int mWidth, mHeight;
public RectView(Context context) {
super(context);
//得到图像
mBitmap = ViewHelper.findBitmapById(context, R.mipmap.view_shape);
//构造渲染器BitmapShader,修改TileMode可以查看效果
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.REPEAT);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.GRAY);
mWidth = mBitmap.getWidth();
mHeight = mBitmap.getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//加个描边
canvas.drawOval(10, 10, mWidth - 290, mHeight - 50, mPaint);
//构建ShapeDrawable对象并定义形状为椭圆
mShapeDrawable = new ShapeDrawable(new OvalShape());
//得到画笔并设置渲染器
mShapeDrawable.getPaint().setShader(mBitmapShader);
//设置显示区域
mShapeDrawable.setBounds(20, 20, mWidth - 300, mHeight - 60);
//绘制shapeDrawable
mShapeDrawable.draw(canvas);
}
}
在Activity使用我们的自定义View:
public class RectActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new RectView(this));
}
}
效果似乎还不错,如果学会了重写onMeasure大概就能自定义View了吧,心里有一些小激动。
小结:
这个Demo中,我们使用到了BitmapShader,ShapeDrawable,Shader.TileMode。
- Shader.TileMode在上一篇博客知识提了一下,它有三种模式:CLAMP(拉伸)、REPEAT(重复)、MIRROR( 镜像);
- BitmapShader在上一篇博客也稍微说了一下,是一个位图渲染对象;
- ShapeDrawable看名字,似乎是绘制形状的;
- 我们给ShapeDrawable的参数是OvalShape,OvalShape直译就是椭圆,所以是绘制椭圆的,查看API,发现OvalShape有一个父类Shape,应该还有其它兄弟。
所以明确我们的学习目标:Shader.TileMode平铺模式的区别;Shape有哪些子类(我们能绘制哪些形状),我们怎么使用它?如果不使用ShapeDrawable可以实现上面的效果么?
Shader.TileMode平铺模式
Shape形状对象
API介绍:
Defines a generic graphical “shape.” Any Shape can be drawn to a Canvas with its own draw() method, but more graphical control is available if you instead pass it to a ShapeDrawable.
查看API发现,Shape有2个直接子类,3个间接子类,他们分别是:
PathShape, RectShape,ArcShape, OvalShape, RoundRectShape。
PathShape
多边形
上一篇博客我写了一个绘制多边形的Demo,用到了Path,相信机智的各位一下子就看懂了它的作用,Demo中根据x、y值不停地画线,最后绘制出一个多边形,不过Path直译既然叫路径,肯定也能画其它线,大家可以自己研究一下。从Path的作用我们也可以看出,PathShape是一个自由度很高的、可以设置多种形状的Shape,想设计奇葩形状的时候考虑使用它(五角星、菱形、六边形等等)。
构造函数:
PathShape(path, stdWidth, stdHeight);
- Path路径对象,来设定图形。
- stdWidth:标准宽度
- stdHeight:标准高度
RectShape
矩形,直接创建实例即可。
构造函数:
RectShape()
ArcShape
扇形
构造函数:
ArcShape(float startAngle, float sweepAngle)
- startAngle:起始角度
- sweepAngle:结束角度
OvalShape
椭圆,直接创建实例即可。
构造函数:
OvalShape()
RoundRectShape
圆角矩形,构造函数的三个参数根据需求设置,不想要可以设置为null,outerRadii和innerRadii需要长度至少为8的float类型数组,每两个float数决定了一个弧度值,一共4个弧度值,分别是: 左上、右上、右下、左下4个位置。
构造函数:
RoundRectShape(float[] outerRadii, RectF inset, float[] innerRadii)
- outerRadii:外矩形 左上、右上、右下、左下圆角半径
- inset:内嵌RectF矩形,4个参数为Margin
- innerRadii:内矩形 左上、右上、右下、左下圆角半径
补充:RoundRectShape的使用Demo
因为RoundRectShape参数看起来不好理解,加一个Demo,如果不设置inset、innerRadii这两个参数,那么他就是圆角矩形了,设置之后,相当于就像从中间挖了一个洞。
/**
* ShapeDrawable对象的使用
* Created by ChenSS on 2016/11/24.
*/
public class RectView extends View {
private BitmapShader mBitmapShader;
private ShapeDrawable mShapeDrawable;
private Shape mShape;
private Bitmap mBitmap;
public RectView(Context context) {
super(context);
//得到位图
mBitmap = ViewHelper.findBitmapById(context, R.mipmap.view_shape);
//构造渲染器BitmapShader,修改TileMode测试效果
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
//外矩形 左上、右上、右下、左下 圆角半径
float[] outerRadii = {20, 20, 20, 20, 60, 70, 80, 200};
//内矩形与外矩形的边距,左、上、右、下
RectF inset = new RectF(100, 100, 200, 200);
//内矩形 圆角半径
float[] innerRadii = {20, 20, 20, 20, 20, 20, 20, 20};
//这三个参数根据需求设置
mShape = new RoundRectShape(outerRadii, inset, innerRadii);
//构建ShapeDrawable对象并定义形状为圆角矩形
mShapeDrawable = new ShapeDrawable(mShape);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//得到画笔并设置渲染器
mShapeDrawable.getPaint().setShader(mBitmapShader);
//设置显示区域
mShapeDrawable.setBounds(20, 20, 1000, 1000);
//绘制shapeDrawable
mShapeDrawable.draw(canvas);
}
关于Xfermode的实战,明天再补充,困了……
安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape