• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.qs.tileimpl
18 
19 import android.content.Context
20 import android.util.AttributeSet
21 import android.widget.LinearLayout
22 
23 /**
24  * [LinearLayout] that can ignore the last child for measuring.
25  *
26  * The view is measured as regularly, then if [ignoreLastView] is true:
27  * * In [LinearLayout.VERTICAL] orientation, the height of the last view is subtracted from the
28  * final measured height.
29  * * In [LinearLayout.HORIZONTAL] orientation, the width of the last view is subtracted from the
30  * final measured width.
31  *
32  * This allows to measure the view and position it where it should, without it amounting to the
33  * total size (only in the direction of layout).
34  */
35 class IgnorableChildLinearLayout @JvmOverloads constructor(
36     context: Context,
37     attributeSet: AttributeSet? = null,
38     defStyleAttr: Int = 0,
39     defStyleRes: Int = 0
40 ) : LinearLayout(context, attributeSet, defStyleAttr, defStyleRes) {
41 
42     var ignoreLastView = false
43 
44     /**
45      * Forces [MeasureSpec.UNSPECIFIED] in the direction of layout
46      */
47     var forceUnspecifiedMeasure = false
48 
onMeasurenull49     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
50         val actualWidthSpec = if (forceUnspecifiedMeasure && orientation == HORIZONTAL) {
51             MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.UNSPECIFIED)
52         } else widthMeasureSpec
53 
54         val actualHeightSpec = if (forceUnspecifiedMeasure && orientation == VERTICAL) {
55             MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.UNSPECIFIED)
56         } else heightMeasureSpec
57 
58         super.onMeasure(actualWidthSpec, actualHeightSpec)
59         if (ignoreLastView && childCount > 0) {
60             val lastView = getChildAt(childCount - 1)
61             if (lastView.visibility != GONE) {
62                 val lp = lastView.layoutParams as MarginLayoutParams
63                 if (orientation == VERTICAL) {
64                     val height = lastView.measuredHeight + lp.bottomMargin + lp.topMargin
65                     setMeasuredDimension(measuredWidth, measuredHeight - height)
66                 } else {
67                     val width = lastView.measuredWidth + lp.leftMargin + lp.rightMargin
68                     setMeasuredDimension(measuredWidth - width, measuredHeight)
69                 }
70             }
71         }
72     }
73 }