[TOC]android
Shader的基本使用很少说了,请参考blog.csdn.net/iispring/ar…,这里咱们只讲解shader使用过程当中的小细节或误区。spring
BitmapShader加载的原图以下:canvas
测试代码以下:bash
public class BitmapShaderView extends View {
private Paint mPaint;
private BitmapShader mShader;
private int mWidth;
private int mHeight;
private int mBitmapWidth;
private int mBitmapHeight;
private Matrix mMatrix;
private int mViewMin;
private int mBitmapMin;
public BitmapShaderView(Context context) {
this(context, null);
}
public BitmapShaderView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_test);
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
mMatrix = new Matrix();
mShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mWidth = getWidth();
mHeight = getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//测试调用函数
testX(canvas);
}
}
复制代码
XML中定义以下:ide
<com.example.robincxiao.androidcanvas.shader.BitmapShaderView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="10dp" />
复制代码
为了进行测试,咱们将BitmapShaderView的宽高都定义为200dp,这个值大于Bitmap的原始宽高。函数
用以下方法替换上面的testX方法测试
private void test0(Canvas canvas) {
canvas.drawColor(Color.GRAY);
mPaint.setShader(mShader);
canvas.drawRect(0, 0, mBitmapWidth, mBitmapHeight, mPaint);
}
复制代码
此时绘制的Rect与Bitmap的实际大小一致,获得以下效果:ui
咱们将test0中代码修改以下this
private void test0(Canvas canvas) {
canvas.drawColor(Color.GRAY);
mPaint.setShader(mShader);
canvas.drawRect(0, 0, mWidth, mHeight, mPaint);
}
复制代码
此时绘制的Rect大小是整个View,远大于Bitmap的实际大小,获得以下效果:spa
对比“1.绘制图形大小与Bitmap大小相等”的结果,此时发现BitmapShader的第二、3个参数有做用了
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
复制代码
小结:当绘制的图形区域大于Bitmap实际大小时(其实这个说法不许备,具体看后面分析),会按照BitmapShader的第二、3个参数的设置进行着色。
咱们将test0中代码修改以下
private void test0(Canvas canvas) {
canvas.drawColor(Color.GRAY);
mPaint.setShader(mShader);
canvas.drawRect(0, 0, mBitmapWidth/2, mBitmapHeight/2, mPaint);
}
复制代码
此时绘制的Rect大小是只有Bitmap实际大小的通常,获得以下效果:
对比“1.绘制图形大小与Bitmap大小相等”的结果,发现源图像只有左上角2/3区域被显示出来了。
总结:在使用BitmapShader进行着色时,要理解绘制图形大小与Bitmap实际大小最终对着色结果的影响。
private void test0(Canvas canvas) {
canvas.drawColor(Color.GRAY);
mPaint.setShader(mShader);
canvas.translate(mWidth/2, mHeight/2);
canvas.drawRect(0, 0, mBitmapWidth, mBitmapHeight, mPaint);
}
复制代码
咱们将坐标系远点移动到BitmapShaderView的中心,获得的结果以下:
发现源Bitmap绘制的启动已经转移到BitmapShaderView的中心,但这还说明不了什么,由于drawRect的启动也是从中心开始的,获得上图所示的结果也是理所固然的。下面咱们再修改test0代码以下:
private void test0(Canvas canvas) {
canvas.drawColor(Color.GRAY);
mPaint.setShader(mShader);
canvas.translate(mWidth/2, mHeight/2);
canvas.drawRect(-mBitmapWidth/2, -mBitmapHeight/2, mBitmapWidth/2, mBitmapHeight/2, mPaint);
}
复制代码
咱们以BitmapShaderView的中心为中心画一个正方形,这个正方形的大小与源Bitmap大小是一致的,获得的结果以下:
(注:BitmapShader的第二、3个参数为REPEAT)
获得这样的结果可能会让不少人以为奇怪,按照“1.绘制图形大小与Bitmap大小相等”的分析,获得的结果应该与“1.绘制图形大小与Bitmap大小相等”的结果是一致的。这就是我想讲清楚的关键点:
LinearGradient、RadialGradient、SweepGradient的使用过程当中,一样要注意上面的问题。