Android画布(二)ShapeDrawable常用函数

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的使用方法:

  1. 通过ImageView的setImageDrawable(drawable)函数将其设置为ImageView的源图片
  2. 通过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和其不在一个维度,功能强大,定制性高,没有可比性

猜你喜欢

转载自blog.csdn.net/qq_39424143/article/details/94002514