Home | History | Annotate | Download | only in view
      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