Android 自定义控件基础

 

目录

一、前言

二、基础代码

(1)自定义View基础流程

(2)onDraw()方法

(3)onMeasure()方法

三、动画

(1)补间动画

(2)帧动画

(3)属性动画

四、SVG标签使用

五、练习Demo

六、Demo地址

七、内容推荐


一、前言

自定义控件一直是Android很重要的一部分,但是大部分时间我们都在处理业务逻辑而很少自己去写控件。因为现在开源的控件比较多,自定义写起来也比较麻烦。但是当我们需要的时候可能就忘了,所以菜鸟作者就买了本书打算系统的学习一遍。这一篇也算是《Android 自定义控件开发入门与实战》读后感。边学边工作也花了一个多月写过几篇笔记,不过后面的隐藏掉了。感觉有点啰嗦所以就凑成这一篇总结。

不管感兴趣与不感兴趣可以浏览一遍,积累一下基础。如果要深入学习这里也推荐两位大神博客

https://www.jianshu.com/p/146e5cec4863

https://blog.csdn.net/harvic880925  启舰《Android 自定义控件开发入门与实战》

 

二、基础代码

《 自定义控件开发入门与实战》这本书我这里主要分成两部分总结:1.自定义View 2.动画 

这里主要根据练习时候写的Demo来进行基础的回顾。先从自定义View开始

(1)自定义View基础流程

  • 1.继承View,或者继承ViewGroup,以及View/ViewGroup的派生类
  • 2.测量 :onMeasure(),用来控制自定义View的宽高
  • 3.位置:onLayout(),在继承ViewGroup的时候需要重写该方法,用来控制子View摆放的位置。
  • 4.绘图:onDraw(),自定义View的主要方法,需要重载或重写该方法来绘制所需要的控件。

先从简单的开始讲起:

(2)onDraw()方法

为什么先说这方法呢 ? 因为前面两个方法不说。我们也可以通过这个方法来简单的实现自定义控件。

先上菜(代码),在介绍这道菜的好处

    fun initPaint(){
        //创建画笔
        paint = Paint()
        //设置画笔颜色
        paint?.setColor(Color.WHITE)
        //设置填充样式 1.Paint.Style.FILL仅填充内部  2.Paint.Style.FILL_AND_STROKE填充内部和描边 3.Paint.Style.STROKE仅描边
        paint?.setStyle(Paint.Style.STROKE)
        //设置画笔宽度 注:画笔样式为Paint.Style.FILL时不显示效果
        paint?.setStrokeWidth(5f)

        paint1 = Paint()
        //设置画笔颜色
        paint1?.setColor(Color.GREEN)
        //设置填充样式 1.Paint.Style.FILL仅填充内部  2.Paint.Style.FILL_AND_STROKE填充内部和描边 3.Paint.Style.STROKE仅描边
        paint1?.setStyle(Paint.Style.STROKE)
        //设置画笔宽度 注:画笔样式为Paint.Style.FILL时不显示效果
        paint1?.setStrokeWidth(5f)
    }
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //平移画布 起始点起始点从(X:0,Y:0)变成(X:100,Y:100)
        canvas?.translate(0f, 100f)
        //裁剪画布 构造方法很多 都是以clip开头
        canvas?.clipRect(0, 0, 500, 500)
        //设置画布颜色
        canvas?.drawColor(Color.BLACK)
//        canvas.drawARGB(0,0,0,255);
//        canvas.drawRGB(0,0,255);

//        绘制直线 startX/startY:起始点X/Y坐标  stopX/stopY:终点X/Y坐标
        canvas?.drawLine(100f, 50f, 450f, 50f, paint)
        //绘制点
        canvas?.drawPoint(50f, 50f, paint)

        //绘制矩形====== >
        val rect = Rect(50, 100, 450, 450)//创建矩形工具类
        //绘制矩形方法
        canvas?.drawRect(rect, paint)//第一种构造方法
//        Rect/RectF用来保存int/float类型数值的矩形结构
//        RectF rectf = new RectF(200,200,400,400);
//        canvas.drawRect(rectf);第二种构造方法
//        canvas.drawRect(200,200,400,400,paint);第三种构造方法
        //   <====== 绘制矩形方法

//      起始点变成(X:50,Y:100)
        canvas?.translate(50f, 100f)
        //绘制路径 ====== >
        val path = Path()
        //设置起始点
        path.moveTo(100f, 50f)
        //第一条直线的终点也是第二条直线的起点
        path.lineTo(50f, 200f)
        path.lineTo(150f, 100f)
        path.lineTo(50f, 100f)
        path.lineTo(150f, 200f)
//        path.lineTo(100, 50);
        //闭环
        path.close()
        //绘制路径方法
        canvas?.drawPath(path, paint)
        // < ======绘制路径

        //绘制弧线  ===== >
        val path1 = Path()
        val rect1 = RectF(200f, 50f, 350f, 200f)
        //弧线主要方法 oval 生成椭圆的矩形,startAngle 弧开始角度, sweepAngle 持续角度
        path1.arcTo(rect1, 180f, 180f, false)
        canvas?.drawPath(path1, paint)
        // < ===== 绘制弧线

//      起始点变成(X:50,Y:100)
        canvas?.translate(50f, 250f)
        //绘制区域 ==== >
        val region = Region(0, 0, 200, 50)
        val region1 = Region(150, -50, 300, 50)
        drawRegion(canvas, region, paint)
        drawRegion(canvas, region1, paint1)
        //区域操作
        // (1)Op.DIFFERENCE:显示region与region1不同区域
        // (2)Op.INTERSECT:显示region与region1相交区域
        // (3)Op.UNION:显示region与region1组合在一起区域
        // (4)Op.XOR:显示region与region1相交之外区域
        // (5)Op.REVERSE_DIFFERENCE:显示region1与region不同区域
        // (6)Op.REPLACE:显示region1区域
        region.op(region1, Region.Op.INTERSECT)
        paint1?.setColor(Color.GRAY)
        drawRegion(canvas, region, paint1)
        // < ==== 绘制区域

        //保存当前画布状态
        canvas?.save()
        //恢复到上一层保存的状态
//        canvas.restore();
    }

    fun drawRegion(canvas : Canvas?,region : Region,paint: Paint?){
        var iter = RegionIterator(region)
        var r = Rect()
        while (iter.next(r)){
            canvas?.drawRect(r,paint)
        }
    }

看完代码我们知道,绘图的前提是先准备好一只画笔(paint),要准备一只怎样的画笔呢。这时候我们可以根据Paint 类提供的API来定义画笔样式。

画笔准备好之后,我们就要考虑绘制什么样的图形呢,要绘制在什么地方。这时候我们需要一张画布,用来显示绘制的图形。

而onDraw(canvas: Canvas?)方法刚好提供了一个画布,并且通过Canvas类提供的API,我们可以绘制各式各样的图形。当然常用的绘图方法就看上面的代码。都用详细的注释。

总结

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值