Drwable看似简单,在平时的应用中也不少,但是一般只是简单的应用,涉及到的覆盖面十分光,今天我们就来扒一扒drawble的的详情
Drawble是对可绘制物件的一般抽象,相对于View缺少一些和事件交互的方法
大致分类:Bitmap,AnimationDrawable,Levels,Nine Patch,Scale,shape,Layers,states
Drawble常用API:
setBounds();控制大小
draw(Canvas canvas) 绘制
自定义Drawble 如圆角图片,圆形图片
先来介绍一个特殊的类Shader,这个类主要是用于渲染图像以及一些几何图形
Shader有几个直接子类:
BitmapShader:主要用于渲染图像
LinearGradient:用来进行线性渲染
RedialGradient:用来进行环形渲染
SweepGradient:扫描渐变 围绕一个中心点,360等安全扫描
ComposeShader:组合渲染,可以和其他几个子类组合起来使用
1:BitampShader
渲染器着色一个位图作为一个纹理,位图可以重复或设置模式
/** * Call this to create a new shader that will draw with a bitmap. * * @param bitmap The bitmap to use inside the shader * @param tileX The tiling mode for x to draw the bitmap in. * @param tileY The tiling mode for y to draw the bitmap in. */ public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY) { mBitmap = bitmap; mTileX = tileX; mTileY = tileY; init(nativeCreate(bitmap, tileX.nativeInt, tileY.nativeInt)); }
Bitmap 在渲染器内使用的位图
tileX 在为位图上X方向瓷砖模式
tileY 在位图上Y方向瓷砖模式
public enum TileMode { /** * replicate the edge color if the shader draws outside of its * original bounds */ CLAMP (0), /** * repeat the shader's image horizontally and vertically */ REPEAT (1), /** * repeat the shader's image horizontally and vertically, alternating * mirror images so that adjacent images always seam */ MIRROR (2); TileMode(int nativeInt) { this.nativeInt = nativeInt; } final int nativeInt; }
TitleModo 一共有三种
CLAMP:如果渲染器超出原始边界范围,会复制范围内边缘染色
REPEADT:横向和纵向的重复渲染器图片,平铺
MIRROR:横向和纵向的重复渲染器图片,这个和REPEAR重复方式不一样,他是以镜像方式平铺
2:LinearGradient
/** Create a shader that draws a linear gradient along a line. @param x0 The x-coordinate for the start of the gradient line @param y0 The y-coordinate for the start of the gradient line @param x1 The x-coordinate for the end of the gradient line @param y1 The y-coordinate for the end of the gradient line @param colors The colors to be distributed along the gradient line @param positions May be null. The relative positions [0..1] of each corresponding color in the colors array. If this is null, the the colors are distributed evenly along the gradient line. @param tile The Shader tiling mode */ public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[], TileMode tile) { if (colors.length < 2) { throw new IllegalArgumentException("needs >= 2 number of colors"); } if (positions != null && colors.length != positions.length) { throw new IllegalArgumentException("color and position arrays must be of equal length"); } mType = TYPE_COLORS_AND_POSITIONS; mX0 = x0; mY0 = y0; mX1 = x1; mY1 = y1; mColors = colors; mPositions = positions; mTileMode = tile; init(nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt)); }
y0: 渐变起初点坐标y位置
x1:渐变终点坐标x位置
y1:渐变终点坐标y位置
colors 渐变的颜色
positions 渐变颜色对应的位置
tile 平铺方式
LinearGradient是线性渐变的,用法如下:
Gradient是居于Shader类,所以我们要通过Paint的setShader方法来设置这个渐变,
代码如下:
Paint paint=new Paint();
//也可采用颜色位置数组方式 LinearGradient lg=new LinearGradient(0,0,100,100, Color.RED,Color.BLUE, Shader.TileMode.MIRROR); paint.setShader(lg);canvas.drawCircle(0,0,200,paint);
下面来看一下例子:
package com.example.drawablestudy.shader; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.OvalShape; import android.util.AttributeSet; import android.view.View; import com.example.drawablestudy.R; /** * @author xuanyouwu * @email [email protected] * @time 2016-01-16 12:51 */ public class MyBitmapShader extends View { public MyBitmapShader(Context context) { super(context); initBitmap(); } public MyBitmapShader(Context context, AttributeSet attrs) { super(context, attrs); initBitmap(); } public MyBitmapShader(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initBitmap(); } private Drawable d; private Bitmap b; private BitmapShader shader; private void initBitmap() { d = getResources().getDrawable(R.drawable.car2); b = ((BitmapDrawable) d).getBitmap(); shader = new BitmapShader(b, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //将图片裁剪为椭圆 //构建ShapeDrawable对象并定义形状为椭圆形 ShapeDrawable sha = new ShapeDrawable(new OvalShape()); sha.getPaint().setShader(shader); sha.setBounds(20, 20, canvas.getWidth(), canvas.getHeight()); sha.draw(canvas); } }
Shape类型详解
Shape类型用来绘制集合图形,易用而轻量化
Shape通常用xml文件方式使用,存放在drawable目录下
shape主要API:
/** * Draw this shape into the provided Canvas, with the provided Paint. * Before calling this, you must call {@link #resize(float,float)}. * * @param canvas the Canvas within which this shape should be drawn * @param paint the Paint object that defines this shape's characteristics */ public abstract void draw(Canvas canvas, Paint paint); /** * Resizes the dimensions of this shape. * Must be called before {@link #draw(Canvas,Paint)}. * * @param width the width of the shape (in pixels) * @param height the height of the shape (in pixels) */ public final void resize(float width, float height) { if (width < 0) { width = 0; } if (height < 0) { height =0; } if (mWidth != width || mHeight != height) { mWidth = width; mHeight = height; onResize(width, height); } }
RectShape 矩形,直角矩形,圆角矩形等
OvalShape 椭圆形,圆形
PathShape 线性,环形等
Ring,Line 环形,环形进度条,线性,实线,虚线
ArcShape 弧形