public BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)
调用这个方法来产生一个画有一个位图的渲染器(Shader)。
bitmap 在渲染器内使用的位图
tileX The tiling mode for x to draw the bitmap in. 在位图上X方向渲染器平铺模式
tileY The tiling mode for y to draw the bitmap in. 在位图上Y方向渲染器平铺模式
TileMode:
CLAMP :如果渲染器超出原始边界范围,会复制范围内边缘染色。
REPEAT :横向和纵向的重复渲染器图片,平铺。
MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。
下面说下Shader的使用步骤:
1. 构建Shader对象
2. 通过Paint的setShader方法设置渲染对象
3.绘制时使用这个Paint对象
activity代码:
package com.example.shader;
import android.app.Activity;
import android.graphics.*;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
public class MyActivity extends Activity {
ImageView image;
int width,height;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
image = (ImageView) findViewById(R.id.image);
width = ValueUtil.dp2px(this,300);
height = ValueUtil.dp2px(this,300);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.tupian); //创建bitmap时会依据屏幕密度缩放,如density为2,drawable-xhdpi下的图片不缩放
Log.e("bitmapwh",bitmap.getWidth()+"+"+bitmap.getHeight()); //352*220
// TileMode:
// CLAMP :如果渲染器超出原始边界(在这个例子中是bitmap的边界)范围,会复制范围内边缘染色,边缘拉伸.
// REPEAT :横向和纵向的重复渲染器图片,平铺。
// MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺,倒影式平铺
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Bitmap bitmapTemp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapTemp);
/* 第一种使用方式*/
Paint paint = new Paint();
paint.setShader(bitmapShader);
canvas.drawRect(new RectF(0, 0, width, height), paint);
// canvas.drawArc(new RectF(0,0,width,height),90,180,false,paint);
// canvas.drawOval(new RectF(0,0,width,height),paint);
/* 第二种使用方式
ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
//得到画笔并设置渲染器
shapeDrawable.getPaint().setShader(bitmapShader);
//设置显示区域
shapeDrawable.setBounds(0, 0, width,height);
//绘制shapeDrawable
shapeDrawable.draw(canvas);
*/
image.setImageBitmap(bitmapTemp);
}
}
效果图:
CLAMP:
REPEAT :
MIRROR :
代码中第一种方式中的canvas.drawOval(new RectF(0,0,width,height),paint)的效果与第二种方式相同,效果图如下:
第二种方式其原理就是canvas的draw系列方法。
我们看
shapeDrawable.draw(canvas);的源码:
public void draw(Canvas canvas) {
final Rect r = getBounds();
final ShapeState state = mShapeState;
final Paint paint = state.mPaint;
final int prevAlpha = paint.getAlpha();
paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha));
// only draw shape if it may affect output
if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadowLayer()) {
final boolean clearColorFilter;
if (mTintFilter != null && paint.getColorFilter() == null) {
paint.setColorFilter(mTintFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
}
if (state.mShape != null) {
// need the save both for the translate, and for the (unknown)
// Shape
final int count = canvas.save();
canvas.translate(r.left, r.top);
onDraw(state.mShape, canvas, paint);
canvas.restoreToCount(count);
} else {
canvas.drawRect(r, paint);
}
if (clearColorFilter) {
paint.setColorFilter(null);
}
}
// restore
paint.setAlpha(prevAlpha);
}
关键代码onDraw(state.mShape, canvas, paint);继续:
继续看shape的draw方法,发现其是一个抽象方法,shape是个抽象类,在本例中,我们找shape子孙类OvalShape的draw方法。/** * Called from the drawable's draw() method after the canvas has been set to * draw the shape at (0,0). Subclasses can override for special effects such * as multiple layers, stroking, etc. */ protected void onDraw(Shape shape, Canvas canvas, Paint paint) { shape.draw(canvas, paint); }
参考资料: http://blog.csdn.net/t12x3456/article/details/10366063@Override public void draw(Canvas canvas, Paint paint) { canvas.drawOval(rect(), paint); }
其参数canvas就是我们最初shapeDrawable.draw(canvas)传入的canvas.
View关于背景drawable的绘制
view的draw()方法中会调用 drawBackground(Canvas canvas)方法,该方法中调用了 background.draw(canvas);而background是 setBackgroundDrawable(Drawable background)设置的。Drawable是抽象类,本例中的ShapeDrawable是其子类。
源码:http://yunpan.cn/c3f2qgcVtNSwP (提取码:2ccf)