本节内容
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>
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方法。
网友评论