1

I've been trying to find a way to avoid having to manually assign components I've created in design mode to array variables, with no success. What I mean is, rather than having to do like this:

val myButtons = ArrayOf (bt0, bt1, bt2,bt3..bt30... etc.

I'd like to know whether there's a way to iterate through all buttons (or ANY other component) created in the app and just call them by their class indexes, just like you can do in HTML:

button class = "buttons"

This way, in HTML, I can create and manipulate as many buttons as I want using JavaScript/jQuery just by using getElementByClassName or $(". buttons") respectively.

Even in old good VisualBasic 6 times, whenever I copied a component and pasted its copy, VB would ask me whether an array of those components should be created and if so, it would assign an index to each one of the new components pasted. This way I could manipulate all of them programmatically with for/each loops or by their indexes individually. Is it impossible to do that in Android Studio (I'm using Kotlin, but I'd gladly shift to Java if it's a language support limitation) and is manually assigning each element at a time to an array variable really the only option that there is? I really hope not...

Thanks in advance!

olfek
  • 3,210
  • 4
  • 33
  • 49

2 Answers2

2

Something like this should work:

private val buttons = ArrayList<Button>() //this is a global variable

private fun loopThrough(parent: ViewGroup) {
    for (i in 0 until parent.childCount) {
        val child = parent.getChildAt(i)

        if (child is Button) buttons.add(child)
        else if (child is ViewGroup) loopThrough(child)
    }
}

To call it initially, first give the root View element of your Activity's XML an ID:

<YourRootLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root">

    <!--...-->

</YourRootLayout>

(YourRootLayout is a placeholder for your actual root layout)

Then, after calling setContentView() in your Activity, call the function:

loopThrough(findViewById<ViewGroup>(R.id.root))

After that finishes, the buttons variable will hold references to all the Buttons in your layout.


Alternatively, you could modify this strategy, giving your buttons sequential IDs, although you lose some readability with that.

TheWanderer
  • 16,775
  • 6
  • 49
  • 63
  • That's what I was looking for! I admit I'm afraid I couldn't understand what the else if portion does in case child is not a button. Looks like it tries to look for buttons inside other Views inside the parent View, is that right? If so, I think it's perfect because my buttons are organized inside TableRows inside a TableLayout, but your solution listed all of my 27 buttons inside those without any TableRow id being needed and it also ignored a 28th button outside the TableView just as expected (that button should be independent). Thank you so much for your help! (couldn't vote up, sorry) – Rodrigo Carvalho Oct 27 '18 at 17:01
  • It's using recursion. It gets passed a ViewGroup (any View that can contain other Views) and then loops through that ViewGroup's children. If it finds a child that's a Button, then it adds it to the list of Buttons. Otherwise, if the child is _also_ a ViewGroup, it'll recursively call the function to then loop through that child ViewGroup. – TheWanderer Oct 27 '18 at 17:05
  • Thanks, I thought it could be the case. It works like a charm. Thanks! – Rodrigo Carvalho Oct 27 '18 at 17:21
0

You can achieve it by parsing xml

Java Code

val inputFile = File("src/in.xml")
val docFactory = DocumentBuilderFactory.newInstance()
val docBuilder = docFactory.newDocumentBuilder()
val doc = docBuilder.parse(inputFile)
val nodes = doc.getElementsByTagName("**buttonTagName**")

imports for this file will be

import org.w3c.dom.Element
import java.io.File
import java.util.*
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.soap.Node
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
Usama
  • 336
  • 1
  • 14
  • Thank you! In this particular case, I think I should still give button Id or tagName manually, isn't it? Still I know there's a way (never done myself tho) to list all I'd tags automatically while reading the XML file. I was thinking about it, but the first answer totally solved my problem. Thank you so much again anyway! – Rodrigo Carvalho Oct 27 '18 at 16:44
  • P.S.: I couldn't vote up for privilege limitations, sorry, but I'll surely use this solution in other ideas for my projects, so thanks again! – Rodrigo Carvalho Oct 27 '18 at 17:06