作用
类似于自定义布局
职责
ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(layout_width)、高度(layout_height)、对齐方式(layout_gravity)等;当然还有margin等;于是乎,ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 ;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。
步骤
- 决定该ViewGroup的LayoutParams
- 重写onMeasure方法
- 重写onLayout方法
- 使用该布局
完整代码实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| class ViewLayout(context: Context, attrs: AttributeSet?):ViewGroup(context,attrs) { override fun generateLayoutParams(attrs: AttributeSet?): ViewGroup.LayoutParams { return MarginLayoutParams(context,attrs) }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val widthMode = MeasureSpec.getMode(widthMeasureSpec) val heightMode = MeasureSpec.getMode(heightMeasureSpec) val sizeWidth = MeasureSpec.getSize(widthMeasureSpec) val sizeHeight = MeasureSpec.getSize(heightMeasureSpec)
measureChildren(widthMeasureSpec, heightMeasureSpec)
var width = 0 var height = 0
val cCount = childCount
var cWidth = 0 var cHeight = 0 var cParams: MarginLayoutParams? = null
var lHeight = 0 var rHeight = 0
var tWidth = 0 var bWidth = 0
for (i in 0..<cCount) { val childView = getChildAt(i) cWidth = childView.measuredWidth cHeight = childView.measuredHeight cParams = childView.layoutParams as MarginLayoutParams
if (i == 0 || i == 1) { tWidth += cWidth + cParams!!.leftMargin + cParams!!.rightMargin }
if (i == 2 || i == 3) { bWidth += cWidth + cParams!!.leftMargin + cParams!!.rightMargin }
if (i == 0 || i == 2) { lHeight += cHeight + cParams!!.topMargin + cParams!!.bottomMargin }
if (i == 1 || i == 3) { rHeight += cHeight + cParams!!.topMargin + cParams!!.bottomMargin } }
width = max(tWidth.toDouble(), bWidth.toDouble()).toInt() height = max(lHeight.toDouble(), rHeight.toDouble()).toInt()
setMeasuredDimension( if (widthMode == MeasureSpec.EXACTLY) sizeWidth else width, if (heightMode == MeasureSpec.EXACTLY) sizeHeight else height ) }
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { val cCount = childCount var cWidth = 0 var cHeight = 0 var cParams: MarginLayoutParams? = null
for (i in 0..<cCount) { val childView = getChildAt(i) cWidth = childView.measuredWidth cHeight = childView.measuredHeight cParams = childView.layoutParams as MarginLayoutParams
var cl = 0 var ct = 0 var cr = 0 var cb = 0
when (i) { 0 -> { cl = cParams!!.leftMargin ct = cParams!!.topMargin }
1 -> { cl = (width - cWidth - cParams!!.rightMargin) ct = cParams!!.topMargin }
2 -> { cl = cParams!!.leftMargin ct = height - cHeight - cParams!!.bottomMargin }
3 -> { cl = (width - cWidth - cParams!!.rightMargin) ct = height - cHeight - cParams!!.bottomMargin } } cr = cl + cWidth cb = cHeight + ct childView.layout(cl, ct, cr, cb) } }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <com.example.studyviewgrope.ViewLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#AA333333" >
<TextView android:layout_width="150dp" android:layout_height="150dp" android:background="#E5ED05" android:gravity="center" android:text="0" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" />
<TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#00ff00" android:gravity="center" android:text="1" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" />
<TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ff0000" android:gravity="center" android:text="2" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" />
<TextView android:layout_width="150dp" android:layout_height="150dp" android:background="#0000ff" android:gravity="center" android:text="3" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" />
</com.example.studyviewgrope.ViewLayout>
|