android studio switch组件的宽高设置_【Android 修炼手册】常用技术篇 -- Android 自定义 View...

e150d048ea0dcd82f96da2b72be4116b.png

这是【Android 修炼手册】系列第 9 篇文章,如果还没有看过前面系列文章,欢迎点击 这里查看~

预备知识

  1. 了解 android 基本开发

看完本文可以达到什么程度

  1. 学会自定义 View 以及其中的关键点

阅读前准备工作

  1. clone CommonTec 项目,其中 myview 是自定义 View 的代码

文章概览

61c37f1b770fad0f26ba2cdd15778ef8.png

自定义 View 内容总体来说还是比较简单,更多的是要满足具体的需求,所以本文内容并不太难,看起来比较愉悦。

在学习如何自定义 View 之前,需要先了解一下 Android 系统里,View 的绘制流程,熟悉了各个流程,我们在自定义过程中也就得心应手了。

一、Android View 绘制流程

Android View 的绘制流程是从 ViewRootImpl 的 performTraversals 开始的,会经历下面的过程。

15b5b35dba1169a3c85db94c3f051ec4.png

所以一个 view 的绘制主要有三个流程,measure 确定宽度和高度,layout 确定摆放的位置,draw 绘制 view 内容。 下面就依次看看这三个步骤。

1.1 onMeasure

onMeasure 是用来测量 View 宽度和高度的,一般情况下可以理解为在 onMeasure 以后 View 的宽度和高度就确定了,然后我们就可以使用 getMeasuredWidth 和 getMeasuredHeight 来获取 View 的宽高了。 我们先看看 View 默认的 onMeasure 里做了什么事情。

setMeasuredDimension

class View {
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

    protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
        // ...
        setMeasuredDimensionRaw(measuredWidth, measuredHeight);
    }

    private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
        mMeasuredWidth = measuredWidth;
        mMeasuredHeight = measuredHeight;

        mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
    }
}

可以看到里面是调用了 setMeasuredDimension,这个方法是设置 View 的测量宽高的,其实内部就是给 mMeasuredWidth 和 mMeasuredHeight 设置了值。之后 getMeasuredWidth 和 getMeasuredHeight 就是获取的这两个值。

getMeasuedWidth/getMeasuredHeight 和 getWidth/getHeight

这里说一下 getMeasuredWidth/getMeasuredHeight 和 getWidth/getHeight 的区别,getMeasuredWidth/getMeasuredHeight 是获取测量宽度和高度,也就是 onMeasure 以后确定的值,相当于是通知了系统我的 View 应该是这么大,但是 View 最终的宽度和高度是在 layout 以后才确定的,也就是 getWidth 和 getHeight 的值。而 getWidth 的值是 right - left,getHeight 也类似。
一般情况下 getMeasuredWidth/getMeasuredHeight 和 getWidth/getHeight 的值是相同的,但是要记住,这两个值是可以不同的。我们可以写个小 demo 看看。

class MyView constructor(context: Context?, attributes: AttributeSet?, defaultAttrStyle: Int) : TextView(context, attributes, defaultAttrStyle) {
    constructor(context: Context?, attributes: AttributeSet?) : this(context, attributes, 0)
    constructor(context: Context?) : this(context, null)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(100, 100)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        setFrame(0, 0, 100, 20)
        super.onLayout(changed
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值