• Android View绘制基础


    View绘制流程

    View 的绘制流程分为三步:在自定义View的时候一般需要重写父类的onMeasure()、onLayout()、onDraw()三个方法,来完成视图的展示过程。当然,这三个暴露给开发者重写的方法只不过是整个绘制流程的冰山一角,更多复杂的幕后工作,都让系统给代劳了。一个完整的绘制流程包括measure、layout、draw三个步骤,其中:

    • measure:测量。系统会先根据xml布局文件和代码中对控件属性的设置,来获取或者计算出每个View和ViewGrop的尺寸,并将这些尺寸保存下来。

    • layout:布局。根据测量出的结果以及对应的参数,来确定每一个控件应该显示的位置。

    • draw:绘制。确定好位置后,就将这些控件绘制到屏幕上。

    三者是先后执行的。
        布局涉及两个过程:测量过程和布局过程。测量过程通过 measure 方法实现,是 View 树自顶向下的遍历,每个 View 在循环过程中将尺寸细节往下传递,当测量过程完成之后,所有的 View 都存储了自己的尺寸。第二个过程则是通过方法 layout 来实现的,也是自顶向下的。在这个过程中,每个父 View 负责通过计算好的尺寸放置它的子 View。
        
    参考:https://blog.csdn.net/weixin_41607932/article/details/124180252

    Android View

    首先,我阅读了View类的文档,并得到了以下解释。
    
    getX() : The visual x position of this view, in pixels.
    
    getY() : The visual y position of this view, in pixels.
    
    getWidth() : Return the width of the your view.
    
    getHeight() : Return the width of the your view.
    
    getTop() : Top position of this view relative to its parent.
    
    getLeft() : Left position of this view relative to its parent.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    view的 getWidth()getHeight():布局文件xml中定义的宽和高。
    
    view的 getX()getY():view左上角顶点在父容器中的位置。
    
    view的 getLeft()getTop()getRight()getBottom():view的左边,上边,右边,下边相对于父容器的距离。
    
    view的 getPaddingLeft()getPaddingTop()getPaddingRight()getPaddingBottom():view的内容到view四边的距离。
    
    MotionEventgetx()getY():以view左上角为坐标原点计算的轴坐标值。
    
    MotionEventgetRawX()getRawY():以屏幕左上角为坐标原点计算的轴坐标值。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    所有这些测量方法都返回像素尺寸( px ),而不是密度像素( dp )。 如果你想转换它,你可以通过调用以获得密度:
    float density = getResources().getDisplayMetrics().density;
    然后将获得的值除以提供的密度,例如:
    int widthDp = (int)(img.getWidth() / density);
    
    您可以从dp获取像素
    float ht_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, ht, getResources().getDisplayMetrics()); 
    float wt_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, wt, getResources().getDisplayMetrics());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    TextView.setTextSize()方法源码

    https://www.codeleading.com/article/97492770835/

    setTextSize(float size)最终调用的是setTextSize(int unit,float size)方法,只是设置了一个默认参数TypedValue.COMPLEX_UNIT_SP,也就是调用setTextSize(float size)方法会默认转换为sp单位。

    这是一个现成的像素转换方法,根据传递过来的unit,来分别计算出不同单位对应的像素值是多少。

        public static float applyDimension(int unit, float value,
                                           DisplayMetrics metrics)
        {
            switch (unit) {
            case COMPLEX_UNIT_PX:
                return value;
            case COMPLEX_UNIT_DIP:
                return value * metrics.density;
            case COMPLEX_UNIT_SP:
                return value * metrics.scaledDensity;
            case COMPLEX_UNIT_PT:
                return value * metrics.xdpi * (1.0f/72);
            case COMPLEX_UNIT_IN:
                return value * metrics.xdpi;
            case COMPLEX_UNIT_MM:
                return value * metrics.xdpi * (1.0f/25.4f);
            }
            return 0;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    dp转px方法

    public int dp2px(Context context, float dpValue){
    		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
    }
    
    • 1
    • 2
    • 3

    android canvas drawText()

    https://www.jb51.net/article/131779.htm

    https://blog.csdn.net/asd199205/article/details/77715224

    Rect rect = new Rect(100,100,500,500);//画一个矩形 
        Paint rectPaint = new Paint(); 
        rectPaint.setColor(Color.BLUE); 
        rectPaint.setStyle(Paint.Style.FILL); 
        canvas.drawRect(rect, rectPaint); 
     
        Paint textPaint = new Paint(); 
        textPaint.setColor(Color.WHITE); 
        textPaint.setTextSize(50); 
        textPaint.setStyle(Paint.Style.FILL); 
        //该方法即为设置基线上那个点究竟是left,center,还是right 这里我设置为center 
        textPaint.setTextAlign(Paint.Align.CENTER); 
     
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); 
        float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top 
        float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom 
     
        int baseLineY = (int) (rect.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式 
     
        canvas.drawText("你好世界",rect.centerX(),baseLineY,textPaint); 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    https://www.jianshu.com/p/c58fc1fc31dd

    https://www.jianshu.com/p/8b97627b21c4

    1.baseline:drawText(text, x, y, paint),基于baseline左下角

    2.Paint.FontMetrics:里面获取字体绘制的属性

  • 相关阅读:
    undefined symbol: _ZN3c104impl8GPUTrace13gpu mmcv
    WhatsApp被封是为什么?如何避免?
    kingdee漏洞金蝶云星空存在弱口令漏洞
    python 编写m3u8视频格式下载小工具
    Nacos安装讲解教程
    【图像增强】基于麻雀搜索算法与双伽马校正的图像自适应增强算法Matlab代码
    kali的三层镜像是什么意思
    RHCSA相关知识点
    新人初学winform程序开发,应该怎样入门?
    华为机试真题实战应用【算法代码篇】-最大嵌套括号深度(附Java、python和C++代码)
  • 原文地址:https://blog.csdn.net/weixin_44008788/article/details/126491625