Basically I'd like to attach a single OnClickListener to multiple views inside a ConstraintLayout.
Before migrating to the ConstraintLayout the views where inside one layout onto which I could add a listener. Now they are on the same layer with other views right under the ConstraintLayout.
I tried adding the views to a android.support.constraint.Group
and added a OnClickListener to it programmatically.
group.setOnClickListener {
Log.d("OnClick", "groupClickListener triggered")
}
However this does not seem to work as of the ConstraintLayout version 1.1.0-beta2
Have I done something wrong, is there a way to achieve this behaviour or do I need to attach the listener to each of the single views?
The Group
in ConstraintLayout
is just a loose association of views AFAIK. It is not a ViewGroup
, so you will not be able to use a single click listener like you did when the views were in a ViewGroup
.
As an alternative, you can get a list of ids that are members of your Group
in your code and explicitly set the click listener. (I have not found official documentation on this feature, but I believe that it is just lagging the code release.) See documentation on getReferencedIds
here.
Java:
Group group = findViewById(R.id.group);
int refIds[] = group.getReferencedIds();
for (int id : refIds) {
findViewById(id).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// your code here.
}
});
}
In Kotlin you can build an extension function for that.
Kotlin:
fun Group.setAllOnClickListener(listener: View.OnClickListener?) {
referencedIds.forEach { id ->
rootView.findViewById<View>(id).setOnClickListener(listener)
}
}
Then call the function on the group:
group.setAllOnClickListener(View.OnClickListener {
// code to perform on click event
})
Update
The referenced ids are not immediately available in 2.0.0-beta2 although they are in 2.0.0-beta1 and before. "Post" the code above to grab the reference ids after layout. Something like this will work.
class MainActivity : AppCompatActivity() {
fun Group.setAllOnClickListener(listener: View.OnClickListener?) {
referencedIds.forEach { id ->
rootView.findViewById<View>(id).setOnClickListener(listener)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Referenced ids are not available here but become available post-layout.
layout.post {
group.setAllOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
val text = (v as Button).text
Toast.makeText(this@MainActivity, text, Toast.LENGTH_SHORT).show()
}
})
}
}
}
This should work for releases prior to 2.0.0-beta2, so you can just do this and not have to do any version checks.