安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape

第一篇博客中,我已经对常用的一些方法做了汇总,这篇文章主要介绍BitmapShader位图渲染、ComposeShader组合渲染,然后看看Xfermode如何实际应用。不过本文还是只重写onDraw一个方法,工欲善其事必先利其器嘛,一个方法一个方法地学,先了解每个对象是干什么的。

ViewHelper(View处理常用方法封装)

安卓自定义控件(一)Canvas、Paint、Shader

安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape

带边框的椭圆形ImageView

先写一个自定义控件,鼓励一下自己。

/**
 * ShapeDrawable对象的使用
 * Created by ChenSS on 2016/11/24.
 */
public class RectView extends View {
    private BitmapShader mBitmapShader;
    private ShapeDrawable mShapeDrawable;
    private Bitmap mBitmap;
    private Paint mPaint;
    private int mWidth, mHeight;

    public RectView(Context context) {
        super(context);
        //得到图像
        mBitmap = ViewHelper.findBitmapById(context, R.mipmap.view_shape);
        //构造渲染器BitmapShader,修改TileMode可以查看效果
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.REPEAT);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.GRAY);

        mWidth = mBitmap.getWidth();
        mHeight = mBitmap.getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //加个描边
        canvas.drawOval(10, 10, mWidth - 290, mHeight - 50, mPaint);
        //构建ShapeDrawable对象并定义形状为椭圆
        mShapeDrawable = new ShapeDrawable(new OvalShape());
        //得到画笔并设置渲染器
        mShapeDrawable.getPaint().setShader(mBitmapShader);
        //设置显示区域
        mShapeDrawable.setBounds(20, 20, mWidth - 300, mHeight - 60);
        //绘制shapeDrawable
        mShapeDrawable.draw(canvas);
    }
}

在Activity使用我们的自定义View:

public class RectActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new RectView(this));
    }
}

效果似乎还不错,如果学会了重写onMeasure大概就能自定义View了吧,心里有一些小激动。

小结:

这个Demo中,我们使用到了BitmapShader,ShapeDrawable,Shader.TileMode。

  1. Shader.TileMode在上一篇博客知识提了一下,它有三种模式:CLAMP(拉伸)、REPEAT(重复)、MIRROR( 镜像);
  2. BitmapShader在上一篇博客也稍微说了一下,是一个位图渲染对象;
  3. ShapeDrawable看名字,似乎是绘制形状的;
  4. 我们给ShapeDrawable的参数是OvalShape,OvalShape直译就是椭圆,所以是绘制椭圆的,查看API,发现OvalShape有一个父类Shape,应该还有其它兄弟。

所以明确我们的学习目标:Shader.TileMode平铺模式的区别;Shape有哪些子类(我们能绘制哪些形状),我们怎么使用它?如果不使用ShapeDrawable可以实现上面的效果么?

Shader.TileMode平铺模式

Shape形状对象

API介绍:

Defines a generic graphical “shape.” Any Shape can be drawn to a Canvas with its own draw() method, but more graphical control is available if you instead pass it to a ShapeDrawable.

查看API发现,Shape有2个直接子类,3个间接子类,他们分别是:

PathShape, RectShape,ArcShape, OvalShape, RoundRectShape。

PathShape

多边形

上一篇博客我写了一个绘制多边形的Demo,用到了Path,相信机智的各位一下子就看懂了它的作用,Demo中根据x、y值不停地画线,最后绘制出一个多边形,不过Path直译既然叫路径,肯定也能画其它线,大家可以自己研究一下。从Path的作用我们也可以看出,PathShape是一个自由度很高的、可以设置多种形状的Shape,想设计奇葩形状的时候考虑使用它(五角星、菱形、六边形等等)。

构造函数:

PathShape(path, stdWidth, stdHeight);

  • Path路径对象,来设定图形。
  • stdWidth:标准宽度
  • stdHeight:标准高度

RectShape

矩形,直接创建实例即可。

构造函数:

RectShape()

ArcShape

扇形

构造函数:

ArcShape(float startAngle, float sweepAngle)

  • startAngle:起始角度
  • sweepAngle:结束角度

OvalShape

椭圆,直接创建实例即可。

构造函数:

OvalShape()

RoundRectShape

圆角矩形,构造函数的三个参数根据需求设置,不想要可以设置为null,outerRadii和innerRadii需要长度至少为8的float类型数组,每两个float数决定了一个弧度值,一共4个弧度值,分别是: 左上、右上、右下、左下4个位置。

构造函数:

RoundRectShape(float[] outerRadii, RectF inset, float[] innerRadii)

  • outerRadii:外矩形 左上、右上、右下、左下圆角半径
  • inset:内嵌RectF矩形,4个参数为Margin
  • innerRadii:内矩形 左上、右上、右下、左下圆角半径

补充:RoundRectShape的使用Demo

因为RoundRectShape参数看起来不好理解,加一个Demo,如果不设置inset、innerRadii这两个参数,那么他就是圆角矩形了,设置之后,相当于就像从中间挖了一个洞。

/**
 * ShapeDrawable对象的使用
 * Created by ChenSS on 2016/11/24.
 */
public class RectView extends View {
    private BitmapShader mBitmapShader;
    private ShapeDrawable mShapeDrawable;
    private Shape mShape;
    private Bitmap mBitmap;

    public RectView(Context context) {
        super(context);
        //得到位图
        mBitmap = ViewHelper.findBitmapById(context, R.mipmap.view_shape);
        //构造渲染器BitmapShader,修改TileMode测试效果
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);

        //外矩形 左上、右上、右下、左下 圆角半径
        float[] outerRadii = {20, 20, 20, 20, 60, 70, 80, 200};
        //内矩形与外矩形的边距,左、上、右、下
        RectF inset = new RectF(100, 100, 200, 200);
        //内矩形 圆角半径
        float[] innerRadii = {20, 20, 20, 20, 20, 20, 20, 20};
        //这三个参数根据需求设置
        mShape = new RoundRectShape(outerRadii, inset, innerRadii);

        //构建ShapeDrawable对象并定义形状为圆角矩形
        mShapeDrawable = new ShapeDrawable(mShape);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //得到画笔并设置渲染器
        mShapeDrawable.getPaint().setShader(mBitmapShader);
        //设置显示区域
        mShapeDrawable.setBounds(20, 20, 1000, 1000);
        //绘制shapeDrawable
        mShapeDrawable.draw(canvas);
    }

关于Xfermode的实战,明天再补充,困了……

时间: 2024-08-05 15:21:00

安卓自定义控件(二)BitmapShader、ShapeDrawable、Shape的相关文章

android 自定义控件二之仿QQ长按删除

自定义Dialog 1.先上个效果图: 虽然效果丑了点,但主要学习修改已有的控件,例如修改Dialog控件 2.一些基本的只是进行了解 Dialog: theme是Dialog的样式,常用样式为: <style name="MyDialogStyle" parent="@android:Theme.Dialog"> <item name="android:windowFrame">@null</item> &l

【安卓自定义控件系列】安卓自定义控件之组合控件

在安卓开发中,谷歌已经为我们提供了许多原生控件,基本上能够满足我们日常的开发需求,但是某些项目中原生控件可能达不到产品所要求的各式各样的酷炫效果或功能效果,这个时候我们只能自己自定义控件来满足项目需求,我们知道自定义控件包括三种方式: 1继承控件,即继承谷歌提供的原生控件,在此基础上提供一些原生控件不具备的功能,如github上各种酷炫效果的开源组件基本上都是采用的这种方式. 2组合控件:即组合多个原生控件来达到某些单个原生控件原本不具备的功能,这个在日常开发中应该是使用的比较多的,如基本上每个

使用安卓生成二维码

网上虽然有很多一键生成二维码的工具,但是通过代码生成一个属于自己的二维码成就感也是不错的,实现方法很简单,需要导入第三方类库 步骤一:导入第三方类库文件:往Android Studio中导入第三方类库文件 步骤二:进行xml文件布局,一个EditText用于输入二维码内容,一个ImageView用于显示生成的二维码,一个生成按钮Button <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quo

android自定义控件(二) 入门,继承View

转载请注明地址:http://blog.csdn.net/ethan_xue/article/details/7313788 ps: 可根据apidemo里LableView,list4,list6学习 文档在dev guide/Framework Topics/User Interface/Building Custom Components 自定义控件的步骤: 1 View的工作原理  2 编写View类  3 为View类增加属性  4 绘制屏幕  5 响应用户消息  6 自定义回调函数

安卓自定义控件的实现

首先自定义控件有什么用呢?当有一种组合控件在很多活动的布局中都要使用到的时候,如果没有自定义控件,那么在每个活动的布局都要写一次重复的代码,这样子就会使代码累赘. 这时就要使用到自定义控件了,自定义控件的步骤如下: 第一步 完成自定义控件的布局文件(.xml文件) 如下面的title.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:/

安卓实现二维码生成和扫描功能,扫描支持直接拍照扫码和相册图片扫码,还加了照明功能

最近在做二维码的生成和扫描,生成二维码相对而言较为简单,扫描相对复杂,遇到的问题较多,但是在实现二维码的生成和扫描之前最重要的一步 就是讲Zxing包导入,后面的内容大部分是使用包中的内容, 那我就从二维码的生成讲起吧! 二维码生成: 直接贴代码了 1 //要转换的地址或字符串,可以是中文,输入内容生成二维码 2 public Bitmap createQRImage(String string) { 3 try { 4 Hashtable<EncodeHintType, String> hi

安卓自定义控件——标题栏的复用

一贯作风,先看效果图,再实现 编写自定义属性文件atts.xml,自定义属性中涉及到的属性有左右两边的button的背景图,中间标题的内容,字体大小,字体颜色. <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="TopBar"> <attr name="leftBackground"

android 自定义控件 (二) 初步认识

最近一直在忙项目,也在不断的面试,每次问道这个自定义控件,好多人云里雾绕的,今天就这个机会,简单做个完全自定义控件的入门吧.上一篇讲了继承已有控件的过程,发现我们只是简答的在封装的布局里操作,并没有重写onDraw,onMeasure,onLayout这些方法.其实继承控件这种形式基本能满足我们大部分的功能,但对于现有控件无法满足的怎么办,那就让我们重写上述三个方法,自己写特定需求的控件.完全自定义控件一般有两种,一种继承View,一种继承Viewgroup.根据view树结构,我们知道View

【天翼杯安卓题二】 爱加密脱壳实战

前言 这个apk使用爱加密加密,加密时间是2017.6月.这个题其实就是个脱壳题,脱完立马见flag.(出题人也太懒了) 题目链接:https://gitee.com/hac425/blog_data/blob/master/app02.apk 壳介绍 爱加密的壳16年年底就已经开始通过 hook dvmResolveClass ,在调用具体方法时解密方法指令,然后将 DexFile结构体中的对应方法的 md->insns 指向 解密后的方法指令数据区,然后进入 真正的dvmResolveCla