1 /* <lambda>null2 * Copyright (C) 2023 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 18 package com.android.wallpaper.picker 19 20 import android.content.Context 21 import android.util.AttributeSet 22 import android.widget.LinearLayout 23 import androidx.core.view.children 24 import androidx.core.view.marginBottom 25 import androidx.core.view.marginEnd 26 import androidx.core.view.marginStart 27 import androidx.core.view.marginTop 28 import com.android.wallpaper.util.ScreenSizeCalculator 29 30 /** 31 * [LinearLayout] that sizes its children using a fixed aspect ratio that is the same as that of the 32 * display, and can lay out multiple children horizontally with margin 33 */ 34 class DisplayAspectRatioLinearLayout( 35 context: Context, 36 attrs: AttributeSet?, 37 ) : LinearLayout(context, attrs) { 38 39 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 40 super.onMeasure(widthMeasureSpec, heightMeasureSpec) 41 42 val screenAspectRatio = ScreenSizeCalculator.getInstance().getScreenAspectRatio(context) 43 val parentWidth = this.measuredWidth 44 val parentHeight = this.measuredHeight 45 val (childWidth, childHeight) = 46 if (orientation == HORIZONTAL) { 47 var childMargins = 0 48 children.forEach { childMargins += it.marginStart + it.marginEnd } 49 val availableWidth = parentWidth - paddingStart - paddingEnd - childMargins 50 val availableHeight = parentHeight - paddingTop - paddingBottom 51 var width = availableWidth / childCount 52 var height = (width * screenAspectRatio).toInt() 53 if (height > availableHeight) { 54 height = availableHeight 55 width = (height / screenAspectRatio).toInt() 56 } 57 width to height 58 } else { 59 var childMargins = 0 60 children.forEach { childMargins += it.marginTop + it.marginBottom } 61 val availableWidth = parentWidth - paddingStart - paddingEnd 62 val availableHeight = parentHeight - paddingTop - paddingBottom - childMargins 63 var height = availableHeight / childCount 64 var width = (height / screenAspectRatio).toInt() 65 if (width > availableWidth) { 66 width = availableWidth 67 height = (width * screenAspectRatio).toInt() 68 } 69 width to height 70 } 71 72 children.forEachIndexed { index, child -> 73 child.measure( 74 MeasureSpec.makeMeasureSpec( 75 childWidth, 76 MeasureSpec.EXACTLY, 77 ), 78 MeasureSpec.makeMeasureSpec( 79 childHeight, 80 MeasureSpec.EXACTLY, 81 ), 82 ) 83 } 84 } 85 } 86