I want to achieve the following abilities:
- Select only one child
View
inside aGridLayout
each time by long clicking it. - A click on the
GridLayout
or any ancestor parent in the visual hierarchy will deselected selected childView
if 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
,focusableInTouchMode
andonClick
listeners, 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 setOnClickListener
in 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
View
and its update methods in theActivity
:On each
GridLayout
child, add theClick
andLongClick
listeners to update or remove the selected view. Mine wereTextView
s added dynamically, but you could easily create a for-loop to retrieve the children:Set the
FocusChange
listener on the parent container:Then, the optional custom
ViewGroup
: it's optional because you could set thefocusable
state by XML and theclickable
listener dynamically, but it seems easier to me. I used this following customClass
as parent container:For example, this is the layout I used:
Hope this will be useful.