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
|
class FixedEndLinearLayout @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val widthSize = MeasureSpec.getSize(widthMeasureSpec) val widthMode = MeasureSpec.getMode(widthMeasureSpec) val heightSize = MeasureSpec.getSize(heightMeasureSpec) val heightMode = MeasureSpec.getMode(heightMeasureSpec) if (childCount != 2) throw RuntimeException("FixedEndLinearLayout must have 2 children.") val wrapChild = getChildAt(0) val fixedChild = getChildAt(1)
measureChild(fixedChild, widthMeasureSpec, heightMeasureSpec) val fixedParams = fixedChild.layoutParams as MarginLayoutParams
val fixedChildWidth = fixedChild.measuredWidth + fixedParams.leftMargin + fixedParams.rightMargin val fixedChildHeight = fixedChild.measuredHeight + fixedParams.topMargin + fixedParams.bottomMargin
val wrapChildWidthSpec = ViewGroup.getChildMeasureSpec( widthMeasureSpec, paddingLeft + paddingRight + fixedChildWidth, wrapChild.layoutParams.width ) val wrapChildHeightSpec = ViewGroup.getChildMeasureSpec( heightMeasureSpec, paddingTop + paddingBottom, wrapChild.layoutParams.height ) wrapChild.measure(wrapChildWidthSpec, wrapChildHeightSpec)
val wrapParams = wrapChild.layoutParams as MarginLayoutParams
val wrapChildWidth = wrapChild.measuredWidth + wrapParams.leftMargin + wrapParams.rightMargin val wrapChildHeight = wrapChild.measuredHeight + wrapParams.topMargin + wrapParams.bottomMargin
val width = wrapChildWidth + fixedChildWidth val height = fixedChildHeight.coerceAtLeast(wrapChildHeight)
start0 = paddingLeft + wrapParams.leftMargin start1 = paddingLeft + wrapChildWidth + fixedParams.leftMargin
setMeasuredDimension( if (widthMode == MeasureSpec.EXACTLY) widthSize else width + paddingLeft + paddingRight, if (heightMode == MeasureSpec.EXACTLY) heightSize else height + paddingTop + paddingBottom )
}
private var start0 = 0 private var start1 = 0
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { val wrapChild = getChildAt(0) val fixedChild = getChildAt(1) val y0 = (measuredHeight - wrapChild.measuredHeight) / 2 val y1 = (measuredHeight - fixedChild.measuredHeight) / 2 wrapChild.layout( start0, y0, start0 + wrapChild.measuredWidth, y0 + wrapChild.measuredHeight ) fixedChild.layout( start1, y1, start1 + fixedChild.measuredWidth, y1 + fixedChild.measuredHeight ) } }
|