I have a problem. In my xml file, I have multiple textViews with the following id's:
txtRow1Column1
txtRow1Column2
txtRow2Column1
txtRow2Column2
txtRow3Column1
txtRow3Column2
txtRow4Column1
txtRow4Column2
Now I filled an array with random numbers between 1..2 and using the 1 or 2 I want to add a text in the textview from the resources. For that I already have the following function:
private fun startNewRound() {
// Define the array for (row, column, value)
val rows = arrayOf<Array<Int>>();
// Fill the array for each row and for each column
for (row in 1..4) {
rows.set(row, emptyArray())
for (column in 1..2) {
rows[row].plus((1..2).random())
}
}
// Show the correct text using the filled array
for (columns in rows) {
for (value in columns) {
val id = "txtRow" rows.indexOf(columns) "Column" (columns.indexOf(value) 1)
when (value) {
1 -> binding."ID HERE".text = getString(R.string.strTrue)
2 -> binding."ID HERE".text = getString(R.string.strFalse)
}
}
}
}
Currently I have added "ID HERE"
instead of the id of the view, because I need to use a string as id to bind to the view. My question is: How can I use that string to find the correct id and be able to bind to that specific view?
CodePudding user response:
Side note, the way you're building that 2D array looks like O(n^2), even if it wasn't going to throw IndexOutOfBoundsExceptions.
The way you're getting the column index won't work. Suppose you have the value 1 twice in a column. indexOf
is going to return 0 both times because it returns the first valid match. Also, using indexOf
inside your 2D loop results in O(n^3) complexity when it could just be O(n).
As to your problem, you can use Resources.getIdentifier()
to find the Int ID of a view so you can find the view using findViewById
. The alternative would be to use reflection on the binding class to find a field with that name, but that's uglier.
fun <T> View.getChildWithName(name: String): T {
val id = context.resources.getIdentifier("id", name, context.packageName)
return findViewById(id)
}
private fun startNewRound() {
val rows = Array(4) { Array(2) { (1..2).random() } }
rows.forEachIndexed { rowIndex, row ->
row.forEachIndexed { colIndex, value ->
val id = "txtRow${rowIndex 1}Column${colIndex 1}"
val view = binding.root.getChildWithName<TextView>(id)
view.text = when (value) {
1 -> getString(R.string.strTrue)
2 -> getString(R.string.strFalse)
}
}
}
}