I want to achieve the following abilities:
- Select only one child
Viewinside aGridLayouteach time by long clicking it. - A click on the
GridLayoutor any ancestor parent in the visual hierarchy will deselected selected childViewif one already selected.
The problem is when when registering a View.OnLongClickListener callback to child View, neither parent GridLayout nor any ancestor registered callbacks (either View.OnClickListener or View.onTouchEvent) called when clicking on them.
How can I get a selected child inside a GridLayout similar to either AdapterView.OnItemSelectedListener or AdapterView.OnItemLongClickListener and solve the above mentioned problem?
What about storing a "selected" view as a global variable, and removing it when its focus changes? By playing with
focusable,focusableInTouchModeandonClicklisteners, you could have the right results. I'm not sure that's the best solution, but it works.What you will need:
[*] If you don't use the optional parent custom Class, you have to set
android:focusable="true"andandroid:focusableInTouchMode="true"on all children of the parent ViewGroup. And you'll have to setOnClickListenerin order to callremoveViewSelected()when the parent ViewGroup is clicked.It will handle all focus change state on parent and child hierarchy, see the output:
I used the following pattern:
Let's preparing the selected
Viewand its update methods in theActivity:On each
GridLayoutchild, add theClickandLongClicklisteners to update or remove the selected view. Mine wereTextViews added dynamically, but you could easily create a for-loop to retrieve the children:Set the
FocusChangelistener on the parent container:Then, the optional custom
ViewGroup: it's optional because you could set thefocusablestate by XML and theclickablelistener dynamically, but it seems easier to me. I used this following customClassas parent container:For example, this is the layout I used:
Hope this will be useful.