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