美文网首页流程
Android开发(24)——测量与布局:子控件和父容器尺寸都不

Android开发(24)——测量与布局:子控件和父容器尺寸都不

作者: 让时间走12138 | 来源:发表于2021-04-18 16:22 被阅读0次

    本节内容

    1.测量单个子控件确定容器尺寸

    一、测量单个子控件确定容器尺寸
    1.先创建一个类,继承自ViewGroup,实现一个构造方法,并把onMeasre和onLayout方法写好。
    class MyViewGroup:ViewGroup {
             constructor(context: Context, attrs: AttributeSet):super(context,attrs){}
          override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
          }
      override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
      }
    }
    
    2.在xml中把前面的类写进去,并在里面添加一个Textview
     <com.example.unknowassociation.MyViewGroup
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:background="@color/colorOrange">
           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="简书是一个创作社区,任何用户均可以在其上进行创作。用户在简书上面可以方便的创作自己的写作作品,互相交流。"
               android:textSize="20sp"
               android:background="@color/colorAccent"/>
       </com.example.unknowassociation.MyViewGroup>
    
    3.在onMeasure方法里面,先定义两个变量来记录容器最终的尺寸
            var resultWidth =0
            var resultHeight = 0
    
    4.获取子控件,并测量子控件
     val child = getChildAt(0)
     measureChild(child,widthMeasureSpec,heightMeasureSpec)
    
    5.由于事先并不知道子控件是wrap_content,match_parent还是写死的,所以我们要先确定容器本身的尺寸和模式
            val parentWidthSize = MeasureSpec.getSize(widthMeasureSpec)
            val parentWidthMode = MeasureSpec.getMode(widthMeasureSpec)
    
    6.先确定宽度,EXACTLY,AT_MOST还是unspecific
     when(parentWidthMode){
                MeasureSpec.EXACTLY ->  resultWidth = parentWidthSize
                MeasureSpec.AT_MOST ->  resultWidth = child.measuredWidth  +2*space
                else ->{
                    resultWidth = parentWidthSize
                }
            }
    
    7.接着确定高度,和前面一样
            val parentHeinghtSize = MeasureSpec.getSize(heightMeasureSpec)
            val parentHeightMode = MeasureSpec.getMode(heightMeasureSpec)
            when(parentHeightMode){
                MeasureSpec.EXACTLY ->  resultHeight = parentHeinghtSize
                MeasureSpec.AT_MOST ->  resultHeight = child.measuredHeight +2*space
                else ->{
                    resultHeight = parentHeinghtSize
                }
            }
    
    8.然后设置父容器尺寸
    setMeasuredDimension(resultWidth,resultHeight)
    
    9.最后在onLayout方法里面布局一下
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
            val child = getChildAt(0)
            var left =space
            var top= space
            var right=left+ child.measuredWidth
            var bottom=top+ child.measuredHeight
            child.layout(left,top,right,bottom)
        }
    
    • 为了方便修改文字,我们可以在strings.xml中添加一个属性
    <string name="title">简书是一个创作社区,任何用户均可以在其上进行创作。
    用户在简书上面可以方便的创作自己的写作作品,互相交流。</string>
    
    • 然后在.xml中把text设置为这个即可。
     android:text="@string/title"
    
    • 间距是很早就设置好的
     private val space = 30
    
    最后运行一下,得到如下结果
    一个控件
    • 结果发现,右边的间距好像消失了。因为我们测量的时候,使用的是measureChild方法,这个完全是依赖于父容器的,默认没有内间距。所以我们换一个方法来测量子控件。
    10.通过 child.measure方法来测量子控件
            val lp = child.layoutParams
            val widthSpec = getChildMeasureSpec(widthMeasureSpec,2*space,lp.width)
            val heightSpec = getChildMeasureSpec(heightMeasureSpec,2*space,lp.height)
            child.measure(widthSpec,heightSpec)
    
    这样右边就也会有间距了,写完之后运行程序得到如下结果。
    修改之后
    • 当自己要额外去测量子控件的时候,就是用child.measure方法。一般时候都可以直接用measureChild方法。

    相关文章

      网友评论

        本文标题:Android开发(24)——测量与布局:子控件和父容器尺寸都不

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