1 /* 2 * Copyright (C) 2017 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 @file:Suppress("NOTHING_TO_INLINE") // Aliases to other public API. 18 19 package androidx.core.view 20 21 import android.view.View 22 import android.view.ViewGroup 23 import androidx.annotation.Px 24 import androidx.annotation.RequiresApi 25 26 /** 27 * Returns the view at [index]. 28 * 29 * @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the count. 30 */ 31 operator fun ViewGroup.get(index: Int) = 32 getChildAt(index) ?: throw IndexOutOfBoundsException("Index: $index, Size: $childCount") 33 34 /** Returns `true` if [view] is found in this view group. */ 35 inline operator fun ViewGroup.contains(view: View) = indexOfChild(view) != -1 36 37 /** Adds [view] to this view group. */ 38 inline operator fun ViewGroup.plusAssign(view: View) = addView(view) 39 40 /** Removes [view] from this view group. */ 41 inline operator fun ViewGroup.minusAssign(view: View) = removeView(view) 42 43 /** Returns the number of views in this view group. */ 44 inline val ViewGroup.size get() = childCount 45 46 /** Returns true if this view group contains no views. */ 47 inline fun ViewGroup.isEmpty() = childCount == 0 48 49 /** Returns true if this view group contains one or more views. */ 50 inline fun ViewGroup.isNotEmpty() = childCount != 0 51 52 /** Performs the given action on each view in this view group. */ 53 inline fun ViewGroup.forEach(action: (view: View) -> Unit) { 54 for (index in 0 until childCount) { 55 action(getChildAt(index)) 56 } 57 } 58 59 /** Performs the given action on each view in this view group, providing its sequential index. */ 60 inline fun ViewGroup.forEachIndexed(action: (index: Int, view: View) -> Unit) { 61 for (index in 0 until childCount) { 62 action(index, getChildAt(index)) 63 } 64 } 65 66 /** Returns a [MutableIterator] over the views in this view group. */ 67 operator fun ViewGroup.iterator() = object : MutableIterator<View> { 68 private var index = 0 69 override fun hasNext() = index < childCount 70 override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() 71 override fun remove() = removeViewAt(--index) 72 } 73 74 /** Returns a [Sequence] over the child views in this view group. */ 75 val ViewGroup.children: Sequence<View> 76 get() = object : Sequence<View> { 77 override fun iterator() = this@children.iterator() 78 } 79 80 /** 81 * Sets the margins in the ViewGroup's MarginLayoutParams. This version of the method sets all axes 82 * to the provided size. 83 * 84 * @see ViewGroup.MarginLayoutParams.setMargins 85 */ 86 inline fun ViewGroup.MarginLayoutParams.setMargins(@Px size: Int) { 87 setMargins(size, size, size, size) 88 } 89 90 /** 91 * Updates the margins in the [ViewGroup]'s [ViewGroup.MarginLayoutParams]. 92 * This version of the method allows using named parameters to just set one or more axes. 93 * 94 * @see ViewGroup.MarginLayoutParams.setMargins 95 */ 96 inline fun ViewGroup.MarginLayoutParams.updateMargins( 97 @Px left: Int = leftMargin, 98 @Px top: Int = topMargin, 99 @Px right: Int = rightMargin, 100 @Px bottom: Int = bottomMargin 101 ) { 102 setMargins(left, top, right, bottom) 103 } 104 105 /** 106 * Updates the relative margins in the ViewGroup's MarginLayoutParams. 107 * This version of the method allows using named parameters to just set one or more axes. 108 * 109 * @see ViewGroup.MarginLayoutParams.setMargins 110 */ 111 @RequiresApi(17) 112 inline fun ViewGroup.MarginLayoutParams.updateMarginsRelative( 113 @Px start: Int = marginStart, 114 @Px top: Int = topMargin, 115 @Px end: Int = marginEnd, 116 @Px bottom: Int = bottomMargin 117 ) { 118 marginStart = start 119 topMargin = top 120 marginEnd = end 121 bottomMargin = bottom 122 } 123