ShapeDrawable常用函数
setBounds()
- 用来指定当前ShapeDrawable在当前控件中的显示位置
setBounds(int left, int top, int right, int bottom)
setBounds(Rect bounds)
getPaint()
(1)
- 通过这个函数得到ShapeDrawable自带的画笔,如果对画笔进行操作,会立即展现在ShapeDrawable上,获取画笔后就可以调用画笔的所有的函数,注意该函数的Paint是在ShapeDrawable的左上角开始绘制的
(2)
- Paint.setShader()可以将Shader的着色器的之前学过的其他用法方面绘制在上面
setAlpha()
//设置透明度取值范围为0~255
setAlpha(int alpha)
setColorFilter(COlorFilter colorFilter)
//设置ColorFilter,是ShapeDrawable自带函数,可以通过getPaint().setColorFilter()进行设置
setColorFilter(COlorFilter colorFilter)
setIntrinsicHeight(int height)
//设置默认高度,当Drawable以setbackGroundDrawable及setImageDrawable方式使用时,会使用默认的宽度和高度来计算当前Drawable的大小和位置,如果不进行设置,则默认的宽高都是-1px
//设置默认的高度
setIntrinsicHeight(int height)
//设置默认的宽度
setIntrinsicWidth(int width)
//设置默认编剧
setPadding(Rect padding)
- eg: 放大镜效果:
public class TelescopeView extends View {
private Bitmap bitmap;
private ShapeDrawable drawable;
//放大镜的半径
private static final int RADIUS = 80;
//放大倍数
private static final int FACTOR = 3;
private final Matrix matrix = new Matrix();
public TelescopeView(Context context){
super(context);
init();
}
public TelescopeView(Context context, AttributeSet attributeSet){
super(context, attributeSet);
init();
}
public TelescopeView(Context context,AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
setLayerType( LAYER_TYPE_SOFTWARE , null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int x = (int)event.getX();
final int y = (int)event.getY();
//绘制Shader的起始位置
matrix.setTranslate(RADIUS - x * FACTOR, RADIUS - y * FACTOR);
drawable.getPaint().getShader().setLocalMatrix(matrix);
drawable.setBounds(x - RADIUS, y - RADIUS, x + RADIUS, y + RADIUS);
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(bitmap == null){
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.niuniu);
bitmap = Bitmap.createScaledBitmap(bitmap1, getWidth(), getHeight(), false);
BitmapShader shader = new BitmapShader(
Bitmap.createScaledBitmap(
bitmap,
bitmap.getWidth()*FACTOR,
bitmap.getHeight()*FACTOR, true),
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
drawable = new ShapeDrawable(new OvalShape());
drawable.getPaint().setShader(shader);
drawable.setBounds(0, 0, RADIUS * 2, RADIUS * 2);
}
canvas.drawBitmap(bitmap,0, 0,null);
drawable.draw(canvas);
}
}
- BitmapScaledBitmap是根据源图像生成一个指定宽度和高度的Bitmap,这里是跟胡bitmap1创建以覆与当前控件同宽、同高的图像,就是将源图像缩放到控件的大小
自定义Drawable
- 在Drawable的自类(ShaoeDrawable和GradientDrawable等)无法通过已有的函数完成指定的绘图功能时,一般会选择自定义Drawable来实现
eg: 自定义Drawable实现圆角矩形
public class CustomDrawable extends Drawable {
/**
* 与View类似,传入的参数是一个Canvas对象,我们只需要调用Canvas的一些方法,效果就会直接显示在Drawable上
* @param canvas
*/
@Override
public void draw(Canvas canvas) {
}
/**
* 当外层调用CustomDrawable的函数时,我们只需要将对应的参数传给CustomDrawable的paint即可
* @param alpha
*/
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
/**
* 当外部需要直到我们自定义的CustomDrawable的显示模式时会调用这个函数
* 四个取值:
* PixelFormat.UNKNOWN表示未知
* PixelFormat.TRANSLUCENT(一般使用该方法)表示当前CustomDrawable的绘图是具有Alpha通道的,即你使用CustomDrawable后,其底部的图现象仍然有可能看到
* PixelFormat.TRANSPARENT表示但概念CustomDrawable是完全透明的,其中什么都没有话,如果使用CustomDrawable,则是完全显示其底部图像
* PixelFormat.OPAQUE表示当前的CustomDrawable是完全没有Alpha通道的,使用CustomDrawable后底层图像是完全被覆盖的,而只显示CustomDrawable本身的图像
* @return
*/
@SuppressLint("WrongConstant")
@Override
public int getOpacity() {
return 0;
}
}
实现圆角矩形
public class CustomDrawable extends Drawable {
private Paint paint;
private Bitmap bitmap;
private BitmapShader bitmapShader;
private RectF bound;
public CustomDrawable(Bitmap bitmap){
this.bitmap = bitmap;
paint = new Paint();
paint.setAntiAlias(true);
}
/**
* 与View类似,传入的参数是一个Canvas对象,我们只需要调用Canvas的一些方法,效果就会直接显示在Drawable上
* @param canvas
*/
@Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(bound, 20, 20, paint);
}
/**
* 当外层调用CustomDrawable的函数时,我们只需要将对应的参数传给CustomDrawable的paint即可
* @param alpha
*/
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
/**
* 当外部需要直到我们自定义的CustomDrawable的显示模式时会调用这个函数
* 四个取值:
* PixelFormat.UNKNOWN表示未知
* PixelFormat.TRANSLUCENT(一般使用该方法)表示当前CustomDrawable的绘图是具有Alpha通道的,即你使用CustomDrawable后,其底部的图现象仍然有可能看到
* PixelFormat.TRANSPARENT表示但概念CustomDrawable是完全透明的,其中什么都没有话,如果使用CustomDrawable,则是完全显示其底部图像
* PixelFormat.OPAQUE表示当前的CustomDrawable是完全没有Alpha通道的,使用CustomDrawable后底层图像是完全被覆盖的,而只显示CustomDrawable本身的图像
* @return
*/
@SuppressLint("WrongConstant")
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
//创建一个与Drawable相同大小的Bitmap作为Drawable的Shader
super.setBounds(left, top, right, bottom);
bitmapShader = new BitmapShader(Bitmap.createScaledBitmap(bitmap, right-left, bottom-top, true), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(bitmapShader);
bound = new RectF(left, top, right, bottom);
}
/**
* 设置默认的宽
* @return
*/
@Override
public int getIntrinsicWidth() {
return bitmap.getWidth();
}
/**
* 设置默认的高
* @return
*/
@Override
public int getIntrinsicHeight() {
return bitmap.getHeight();
}
}
Drawable的使用方法:
- 通过ImageView的setImageDrawable(drawable)函数将其设置为ImageView的源图片
- 通过View的setBackgroundDrawable(drawable)函数将其设置为背景图片
- setImageDrawable(drawable):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AndroidHuabu.DrawableView.DrawableViewActivity">
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#881111"
android:scaleType="center"/>
</LinearLayout>
public class DrawableViewActivity extends AppCompatActivity {
private ImageView imageView;
private CustomDrawable customDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawable_view);
imageView = (ImageView)findViewById(R.id.img);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.niuniu);
customDrawable = new CustomDrawable(bitmap);
imageView.setImageDrawable(customDrawable);
}
}
- setBackgroundDrawable(drawable)函数:
<TextView
android:id="@+id/tv"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="wjx"
android:textColor="#6D6D1C"/>
textView.setBackground(customDrawable);
注意:
- 当使用setImageDrawable(drawable)函数来设置ImageView数据源时,自定义Drawable的位置和大小与ImageView的scaleType有关
- 当使用setBackgroundDrawablle(drawable)函数来设置View的背景时,自定义Drawable的宽、高与控件带线啊哦一致,控件的宽和高则选取本身宽和高和自定义Drawable的宽和高中的最大值
自定义Drawable和自定义View的区别:
- 自定义Drawable主要用于设置Drawable的函数中,用于替代Bitmap用于View中
- 自定义View和其不在一个维度,功能强大,定制性高,没有可比性