I am adding some EditText views programmatically to a LinearLayout and for some reason I am not able to adjust the width of these EditText views. the goal I am trying to accomplish is have all the EditText views be of the same width, and that width is determined by whichever EditText ends up being the widest since they are using the WRAP_CONTENT option. Originally, I couldn't get the maxWidth to update at all, then I read about the viewObserverTree solution you can see in the middle of my function below. The Toast just outside of the if (maxWidth < viewWidth)
block shows the correct amount for each of the views, but at the bottom where the for loop is supposed to be iterating through the children contained in a LinearLayout, it reads maxWidth as 0 and ends up looking weird since the views get squished to a width of 0. I am not sure why this is occuring and what to do about it. Below is the function:
private fun createTimerFields(v : View, timeUnit : String) {
if (v.findViewById<LinearLayout>(R.id.timer_fields) != null) {
timerContainer.removeView(v.findViewById<LinearLayout>(R.id.timer_fields))
}
var maxWidth = 0
val timeUnitsArray = ArrayList(listOf(*resources.getStringArray(R.array.time_units)))
val timerFieldsLayout = LinearLayout(requireContext())
val linearLayoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)
timerFieldsLayout.layoutParams = linearLayoutParams
timerFieldsLayout.orientation = LinearLayout.HORIZONTAL
timerFieldsLayout.id = R.id.timer_fields
for (unit in 0..timeUnitsArray.indexOf(timeUnit)) {
val timeUnitEditText = EditText(requireContext())
timeUnitEditText.layoutParams = linearLayoutParams
timeUnitEditText.hint = "${timeUnitsArray[unit][0]}${timeUnitsArray[unit][0]}"
val mVTO: ViewTreeObserver = timerFieldsLayout.viewTreeObserver
mVTO.addOnGlobalLayoutListener {
if (timeUnitEditText != null) {
val viewWidth: Int = timeUnitEditText.width
if (maxWidth < viewWidth) {
maxWidth = viewWidth
}
Toast.makeText(requireContext(), maxWidth.toString(), Toast.LENGTH_SHORT).show()
// any operation based on viewWidth is to be done here
}
}
if (unit == 0) {
var spacePadding = Space(requireContext())
spacePadding.layoutParams = LinearLayout.LayoutParams(
utils.convertDpsToPixels(requireContext(), 15F),
LinearLayout.LayoutParams.MATCH_PARENT)
timerContainer.addView(spacePadding, 0)
}
timerFieldsLayout.addView(timeUnitEditText, 0)
//Toast.makeText(requireContext(), timeUnitEditText.width.toString(), Toast.LENGTH_SHORT).show()
}
timerContainer.addView(timerFieldsLayout, 0)
for (child in 0 until timerFieldsLayout.childCount - 1) {
var currentView = timerFieldsLayout.getChildAt(child)
if (currentView.javaClass.simpleName == "EditText" ) {
(currentView as EditText).width = maxWidth
Toast.makeText(requireContext(), (currentView as EditText).width.toString(), Toast.LENGTH_SHORT).show()
}
}
}
Just so the tree of how I am trying to add things is clear, it goes like this:
LinearLayout for row
LinearLayout for inflated timer view
LinearLayout for timer view contents (needed for a Space view beneath the contents)
LinearLayout for the dynamically added fields of the timer
LinearLayout containing the fields
Space view followed by dynamically added EditText views detailed in above function