Android 自定义View浅谈

作者: 没有了遇见 | 来源:发表于2022-06-28 09:04 被阅读0次

引言

自定义View 字面意思就是自己定义一个View以此完成自己的业务需求.当你在百度/Google cv大法搞不定你的业务需求的时候,这个时候就需要你自定义一个View来完成你的需求了.

背景简介

Android 系统为我们提供了各种各样的常见控件来满足我们的日常需求,但是谁能不爱美呢.常见的系统控件满足了我们的功能需要,但是原生控件确实不好看这个时候就需要我们做改造了 或者更改Style 或者改颜色背景.但是一些需求原生控件满足不了日益强大的UI的时候我们只能自定义View来实现,比如说各种奇形怪状的控件,各种奇怪的进度条...这个时候我们就需要自己写了.一切从爹开始,继承爹的财产好干事儿,我们继承View这个爹 然后自定义我们的控件就行了

页面展示的层次

了解自定义View以前,咱们先简单介绍一下Android视图层次结构以及DecorView.在Android Studio layout inspector 中能看到页面的布局层次


视图层次.png 屏幕展示的层级.png

上图可以看到整个页面分为状态栏,ActionBar 和setContent()中的引用的布局content

自定义View的绘制流程

自定义View 的流程,View这个父布局给我们提供了很多方法(有兴趣的同学可以去看看源码),我们用到的比较多的是onMeasure().onLayout(),onDraw();

  • onMeasure() : 测量
  • onLayout() :摆放
  • onDraw() :绘制

整体流程:

View的绘制从ActivityThread类中Handler的处理RESUME_ACTIVITY事件开始,在执行performResumeActivity之后,创建Window以及DecorView并调用WindowManager的addView方法添加到屏幕上,addView又调用ViewRootImpl的setView方法,最终执行performTraversals方法,依次执行performMeasure,performLayout,performDraw。也就是view绘制的三大过程。

1.onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)方法是测量一个View的宽高,onMeasure()调用setMeasuredDimension(w,h)方法设置View的宽高

//获取测量模式
var widthMode=MeasureSpec.getMode(widthMeasureSpec)

 widthMode 设置布局的主要模式为
          //最多不超过父布局模式
          --MeasureSpec.AT_MOST:(wrap_content)父布局根据子布局填充   
         //精确模式
          --MeasureSpec.EXACTLY:(much_content,fill_content,100dp)父布局已经确定了确切尺寸。子布局不能超过父布局
        //不指定模式
          --MeasureSpec.UNSPECIFIED:父布局没有对子布局施加任何约束。 可以是任何大小

2.onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) 设置控件居于屏幕位置(0.0)

changed: 是否有变化
left,top,right,bottom  左上右下两个点的坐标  矩形的左上角和右下角

3.onDraw(canvas: Canvas?) 绘制方法 将控件绘制到手机屏幕上

1.canvas.drawText(@NonNull String text, float x, float y, @NonNull Paint paint) 绘制文字的方法

      String text:文字参数
      float x:开始位置
      float y: 基线位置(文字绘制的位置)
                - 获取基线方法
                fun getBaseline(p: Paint): Float {
                        val fontMetrics: Paint.FontMetrics = p.fontMetrics
                        return height / 2 + ((fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent) }
      Paint paint: 画笔(设置绘制的 宽度,颜色,模式,以及文字大小,抗锯齿)      
    2.canvas?.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
        @NonNull Paint paint):绘制指定的弧,将缩放比例以适合指定的椭圆

    RectF() :RectF拥有一个矩形的四个浮点坐标。 矩形是由其4个边(左,上,右下)的坐标表示
    startAngle: 开始的角度
    sweepAngle:旋转的角度
    useCenter:是否填充中心
    paint:画笔
  3. drawCircle(float cx, float cy, float radius, @NonNull Paint paint):绘制圆形
    cx:圆心的x坐标
    cy:圆心的y坐标
    radius:半径大小
    paint: 画笔

其他重要方法

  1 : invalidate() 刷新绘制
  2 : canvas.save() 保存当前矩阵并将剪辑裁剪到私有堆栈上。
  3 : canvas.restore() 这个方法调用平衡了对save()的先前调用,并用于删除所有自上次保存调用以来对矩阵/剪辑状态的修改。 (和save()搭配使用)

总结

感觉这个自定义View 还是有很多没梳理到 暂时先这样,回头接着研究

相关文章

网友评论

    本文标题:Android 自定义View浅谈

    本文链接:https://www.haomeiwen.com/subject/kimnvrtx.html