Use Kotlin to perform function operations on ViewGroup views.

Source: Internet
Author: User

Use Kotlin to perform function operations on ViewGroup views.

Original article title: Functional operations over Views in ViewGroup using Kotlin

Link: http://antonioleiva.com/functional-operations-viewgroup-kotlin/

Antonio Leiva (http://antonioleiva.com/about)

Original article published:

 

 

Set, iteration, array, sequence... all these share a set of usefulFunctions. These functions can be used to convert, sort, and perform other operations on their elements.. However, due to the class constructor, some functions are not available in the Android SDK.

For example, we cannot directly obtainViewGroupInternal View list, so these operations are not available. But not all are lost. In Kotlin, We have methodsPrepare any data for these operations. Easy to learn: we only need to create oneSequence. In our example, Sequence will be a group of orderedView. We only needImplement a function and returnIterator.

If we haveSequenceThe functional operation field opens the door for us to use them. So let's start with it.

Note: Read the end of the article

As lakedaemon666 suggested in the comments, there is a simpler method without Sequence to get the same result. I will keep the original record, but I suggest you look at the alternative solution.

 

Create the Sequence of ViewGroup

As mentioned above, we will create an iterator which must know whether there is a next item and which is the next one. We also create an extension function to provide a simple method for any ViewGroup and inheritance class:

 1 fun ViewGroup.asSequence(): Sequence<View> = object : Sequence<View> { 2   3     override fun iterator(): Iterator<View> = object : Iterator<View> { 4         private var nextValue: View? = null 5         private var done = false 6         private var position: Int = 0 7   8         override public fun hasNext(): Boolean { 9             if (nextValue == null && !done) {10                 nextValue = getChildAt(position)11                 position++12                 if (nextValue == null) done = true13             }14             return nextValue != null15         }16  17         override fun next(): View {18             if (!hasNext()) {19                 throw NoSuchElementException()20             }21             val answer = nextValue22             nextValue = null23             return answer!!24         }25     }26 }

 

Retrieve the recursive list of views

Obtain a View list and perform function operations on it. Therefore, we can first create a top-level view list, and then use it to recursively retrieve the listViewGroup.

Let'sViewGroupCreate newExtended attributes. Extended attributes are very similar to extended functions and can be used in any class:

1 public val ViewGroup.views: List<View>2     get() = asSequence().toList()

 

We can use this to create a recursive function that returns anyViewGroupAll internalView:

1 public val ViewGroup.viewsRecursive: List<View>2     get() = views flatMap {3         when (it) {4             is ViewGroup -> it.viewsRecursive5             else -> listOf(it)6         }7     }

 

UseflatMapTo convert Multiple lists of all results to one list. It traverses any view. If it is a ViewGroup, it also traverses its own view. Otherwise, only one list is returned.

 

Usage example

Now, we getviewRecursiveAttribute to perform any operation we want. Here you can see two examples. I created such a simple layout:

1 <RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android" 2 xmlns: tools = "http://schemas.android.com/tools" 3 android: id = "@ + id/container" 4 android: layout_width = "match_parent" 5 android: layout_height = "match_parent" 6 android: paddingBottom = "@ dimen/activity_vertical_margin" 7 android: paddingLeft = "@ dimen/8 android: paddingRight = "@ dimen/activity_horizontal_margin" 9 android: paddingTop = "@ dimen/activity_vertical_margin" 10 tools: context = ". mainActivity "> 11 12 <TextView13 android: layout_width =" wrap_content "14 android: layout_height =" wrap_content "15 android: text = "@ string/hello_world"/> 16 17 <FrameLayout18 android: layout_width = "match_parent" 19 android: layout_height = "wrap_content" 20 android: layout_centerInParent = "true"> 21 22 <TextView23 android: layout_width = "wrap_content" 24 android: layout_height = "wrap_content" 25 android: text = "Hello Java"/> 26 27 <TextView28 android: layout_width = "wrap_content" 29 android: layout_height = "wrap_content" 30 android: layout_gravity = "center_horizontal" 31 android: text = "Hello Kotlin"/> 32 33 <TextView34 android: layout_width = "wrap_content" 35 android: layout_height = "wrap_content" 36 android: layout_gravity = "end" 37 android: text = "Hello Scala"/> 38 39 </FrameLayout> 40 41 <LinearLayout42 android: layout_width = "match_parent" 43 android: layout_height = "wrap_content" 44 android: layout_alignParentBottom = "true" 45 android: orientation = "horizontal"> 46 47 <CheckBox48 android: layout_width = "wrap_content" 49 android: layout_height = "wrap_content" 50 android: text = "Check 1"/> 51 52 <CheckBox53 android: layout_width = "wrap_content" 54 android: layout_height = "wrap_content" 55 android: text = "Check 2"/> 56 57 <CheckBox58 android: layout_width = "wrap_content" 59 android: layout_height = "wrap_content" 60 android: text = "Check 3"/> 61 62 <CheckBox63 android: layout_width = "wrap_content" 64 android: layout_height = "wrap_content" 65 android: text = "Check 4"/> 66 67 </LinearLayout> 68 69 </RelativeLayout>

 

For exampleMainActivity.onCreate()Medium,This Code can be applied. It setsHello Kotlin!Convert the string to uppercase letters, and select the even check box:

 1 val container: ViewGroup = find(R.id.container) 2 val views = container.viewsRecursive 3   4 // Set Kotlin TextView to Upper 5 val kotlinText = views.first { 6     it is TextView && it.text.toString().contains("Kotlin") 7 } as TextView 8 kotlinText.text = kotlinText.text.toString().toUpperCase() 9  10 // Set even checkboxes as checked, and odd as unchecked11 views filter {12     it is CheckBox13 } forEach {14     with(it as CheckBox) {15         val number = text.toString().removePrefix("Check ").toInt()16         setChecked(number % 2 == 0)17     }18 }

 

 

Alternative solution

As mentioned in the comments of lakedaemon666 (Thank you for your explanation), if we traverse the entire sequence, it makes no sense to create a sequence. For example, when reading files by row, sequence is a lazy iteration. Only required items are required. However, we need to use all items, so a simple list is enough.

In addition, there are many simple ways to generate a View list. We can generate the View index list based on the Value Field and map them to the View list we need. All of this is just one line:

1 public val ViewGroup.views: List<View>2     get() = (0..getChildCount() - 1) map { getChildAt(it) }

 

Summary

This is a boring example, but this concept may function all your code and stop relying on typical iterative programming loops and other control flows.

Remember that from my book "Kotlin for Android Developers", you can learn this and many other features of Kotlin. You will learn Kotlin by creating an Android APP from 0.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.