I have a set of 20 XML buttons that I need to access to programmatically change their margins based on a toggle. After heavy research and tons of failed attempts, I was finally able to manipulate them all perfectly without ruining other non-margin parameters like constraints, like this:
private fun setMargin(sizeInDP: Int) {
val marginInDp = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
sizeInDP.toFloat(),
resources.displayMetrics
).toInt()
var parameters = binding.buttonClear.layoutParams as ConstraintLayout.LayoutParams
parameters.setMargins(
parameters.leftMargin, marginInDp, parameters.rightMargin, marginInDp
) // left, top, right, bottom
binding.buttonClear.layoutParams = parameters
parameters = binding.buttonEquals.layoutParams as ConstraintLayout.LayoutParams
parameters.setMargins(
parameters.leftMargin, marginInDp, parameters.rightMargin, marginInDp
) // left, top, right, bottom
binding.buttonEquals.layoutParams = parameters
// (... 20 total)
parameters = binding.buttonZero.layoutParams as ConstraintLayout.LayoutParams
parameters.setMargins(
parameters.leftMargin, marginInDp, parameters.rightMargin, marginInDp
) // left, top, right, bottom
binding.buttonZero.layoutParams = parameters
}
However, this creates 119 lines of repeated code. I tried several ways, like iterating over an array with a for loop or a function, but in both of these I was unable to access my actual XML buttons. Two of my best attempts:
for (button in buttonsArray) {
val parameters = button.layoutParams as ConstraintLayout.LayoutParams
parameters.setMargins(
parameters.leftMargin, marginInDp, parameters.rightMargin, marginInDp
) // left, top, right, bottom
binding.{ button.id } = parameters // this does not work
}
fun test(myButton){
val parameters = myButton.layoutParams as ConstraintLayout.LayoutParams
parameters.setMargins(
parameters.leftMargin, marginInDp, parameters.rightMargin, marginInDp
) // left, top, right, bottom
binding.{ myButton.id } = parameters // this does not work
}
test(binding.buttonClear.layoutParams)
test(binding.buttonEquals.layoutParams)
// (... 20 total)
test(binding.buttonBackspace.layoutParams)
In the last example, I know 'myButton' is just a local copy of the button inside test(), so assigning parameters to it would not work. Same with the array, assigning to 'button' just assigns to the array element, not the XML button.
The problem is trying to access/reference the XML button dynamically, I honestly have no idea how. Is something similar to this
binding.{ button.id } = parameters
even possible? If so, how?