Sorry if the code is a bit convoluted, I've been spamming things out trying to fix this for ages.
I create children within a layout and track the number in which they were added, then compare them so we know which sets belong to which exercises. On click of the arrow, the set information should collapse but only the last view of each exercise does.
fun listeners() {
for (i in childCount3) {
val imageButton: TextView = binding.parentLinearLayout.getChildAt(i).weightTxt
val fragment = EditSetFragment()
imageButton.setOnClickListener {
supportFragmentManager.beginTransaction().replace(R.id.parent_linear_layout, fragment).commit()
}
}
// childList = 10 | childList2 = [0,3,6,8] | childList3 = [1,2,4,5,7,9]
var testCount = 0
var testCount2 = 0
for (i in 0 until childCount2.size) {
var matches = ArrayList<Int>()
val imageButton: ImageButton = binding.parentLinearLayout.getChildAt(childCount2[i]).expandCard
Log.d("I ", i.toString())
for (k in 0 until childCount3.size) {
Log.d("k ", k.toString())
Log.d("CHECKER ", binding.parentLinearLayout.getChildAt(childCount2[i]).instanceTxtEx.text.toString() binding.parentLinearLayout.getChildAt(childCount3[k]).instanceTxt.text).toString()
if(binding.parentLinearLayout.getChildAt(childCount2[i]).instanceTxtEx.text == binding.parentLinearLayout.getChildAt(childCount3[k]).instanceTxt.text) {
matches.add(childCount3[k])
Log.d("MATCH ", i.toString())
imageButton.setOnClickListener{
binding.parentLinearLayout.getChildAt(childCount3[k]).visibility = GONE
}
}
}
}
}
CodePudding user response:
It's a little hard to follow what you're doing, but I think you're going over each item in childCount2
, grabbing its expand button, then trying to add a click listener for each child that item has in childCount3
?
The problem is you can only set one click listener on a View
, so in your loop you're not adding multiple listeners which each hide a button, you're replacing the current listener each time. So it ends up only hiding the last item you set a listener for.
If you're adding these items to the layout programmatically, can't you just store a list of the children of each top-level item? That way you can just set the listener once for each button, and in it just reference your list of its children. Something like this:
val parentsAndChildren = mutableMapOf<View, MutableList<View>>()
// Add your top-level (childCount2) views here, mapped to an empty list
// As you add children (childCount3), grab their parent's list and add the child to it
fun setUpCollapseButtons() {
// iterate over all the parents and set a click listener on their buttons
parentsAndChildren.keys.forEach { parent ->
parent.expandCard.setOnClickListener {
// grab the current list of children for this parent, and do the thing
parentsAndChildren[parent].forEach { it.visibility = GONE }
// could also do { it.visibility = if (it.visibility == VISIBLE) GONE else VISIBLE } for a toggle
}
}
}
I'm not 100% sure how you're referencing things like expandCard
when getChildAt
just returns a View
, but you can use findViewById
on each parent
when you're setting up the click listeners. Hopefully that gives you the idea - it's much easier to just keep track of the views themselves, instead of having to go digging for them (and doing text comparisons to match them)
If you still want to do it this way, here's how you can set one click listener on each:
// collect all the parent Views
val parents = childCount2.map { i -> binding.parentLinearLayout.getChildAt(i) }
parents.forEach { parent ->
// collect all its children
val children = childCount3.map { j -> binding.parentLinearLayout.getChildAt(j) }
.filter { child -> parent.instanceTxtEx.text == child.instanceTxtEx.text }
// add a single click listener to the parent, make it affect all the children
parent.expandCard.setOnClickListener {
children.forEach { it.visibility = GONE }
}
}
There are fancier ways to collect the parents and children, but hopefully that makes sense - you need to collect them all before you can set the click listener that affects them all