Программный поиск всех кнопок в группе просмотра

Я пытался найти способ избежать необходимости вручную назначать компоненты, которые я создал в режиме разработки, переменным массива, но безуспешно. Я имею в виду, вместо того, чтобы делать вот так:

val myButtons = ArrayOf (bt0, bt1, bt2,bt3..bt30... и др.

Я хотел бы знать, есть ли способ перебрать все кнопки (или ЛЮБОЙ другой компонент), созданные в приложении, и просто вызвать их по их индексам классов, как вы можете это сделать в HTML:

button class = "buttons"

Таким образом, в HTML я могу создавать и управлять любым количеством кнопок, используя JavaScript / jQuery, просто используя getElementByClassName или $(". buttons") соответственно.

Даже в старом добром VisualBasic 6 раз всякий раз, когда я копировал компонент и вставлял его копию, VB спрашивал меня, нужно ли создавать массив этих компонентов, и если да, он назначал индекс каждому из новых вставленных компонентов. Таким образом, я мог программно управлять всеми ними с помощью циклов for / each или их индексов индивидуально. Невозможно сделать это в Android Studio (я использую Kotlin, но я бы с радостью перешел на Java, если это ограничение поддержки языка) и вручную назначает каждый элемент за раз переменной массива, действительно единственный вариант, который есть является? Я очень надеюсь, что нет ...

Заранее спасибо!

1
0
973
2

Ответы 2

Примерно так должно работать:

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)
    }
}

Чтобы вызвать его изначально, сначала дайте корневому элементу View XML вашей Activity идентификатор:

<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)

Затем, после вызова setContentView() в вашей деятельности, вызовите функцию:

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

После этого переменная buttons будет содержать ссылки на все кнопки в вашем макете.


В качестве альтернативы вы можете изменить эта стратегия, присвоив вашим кнопкам последовательные идентификаторы, хотя при этом вы теряете некоторую удобочитаемость.

Вот что я искал! Признаюсь, я боюсь, что не могу понять, что делает часть else if в случае, если дочерний элемент не является кнопкой. Похоже, он пытается искать кнопки внутри других представлений внутри родительского представления, верно? Если так, я думаю, что это идеально, потому что мои кнопки организованы внутри TableRows внутри TableLayout, но ваше решение перечислило все мои 27 кнопок внутри тех, без какого-либо идентификатора TableRow, и оно также проигнорировало 28-ю кнопку вне TableView, как и ожидалось (это кнопка должна быть независимой). Спасибо большое за вашу помощь! (не смог проголосовать, извините)

Rodrigo Carvalho 27.10.2018 19:01

Он использует рекурсию. Ему передается ViewGroup (любое представление, которое может содержать другие представления), а затем циклически перебирать дочерние элементы этой ViewGroup. Если он находит дочерний элемент, являющийся кнопкой, он добавляет его в список кнопок. В противном случае, если дочерний элемент является также ViewGroup, он будет рекурсивно вызывать функцию, чтобы затем пройти через эту дочернюю ViewGroup.

TheWanderer 27.10.2018 19:05

Спасибо, я думал, что это может быть так. Работает как часы. Спасибо!

Rodrigo Carvalho 27.10.2018 19:21

Вы можете добиться этого, проанализировав xml

Код Java

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

импорт для этого файла будет

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

Спасибо! В этом конкретном случае, я думаю, мне все равно следует указывать идентификатор кнопки или tagName вручную, не так ли? Тем не менее я знаю, что есть способ (я никогда не делал этого сам) автоматически перечислять все теги, которые я помечал, при чтении файла XML. Я думал об этом, но первый ответ полностью решил мою проблему. В любом случае большое вам спасибо!

Rodrigo Carvalho 27.10.2018 18:44

P.S .: Я не смог проголосовать за ограничение привилегий, извините, но я обязательно буду использовать это решение в других идеях для своих проектов, так что еще раз спасибо!

Rodrigo Carvalho 27.10.2018 19:06

Другие вопросы по теме