Problem
Track any click occurring on any clickable View
in the app.
Possible solution
This solution is a bit heavy and requires certain discipline from your side (do not use setOnClickListener()
for other purposes but tracking clicks).
Add a View.OnClickListener
to any View
in your base Activity
or any Activity
, for which you would like to track down click events. Start doing this only when the global layout has finished loading (by adding an OnGlobalLayoutListener
) to the root view. So, the code look could look as follows:
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
View decorView = getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(() ->
printClickedViews(getWindow().getDecorView())
);
}
private void printClickedViews(View currentView) {
if (currentView == null) {
return;
}
currentView.setOnClickListener(v -> {
Toast.makeText(v.getContext(), "Clicked on " + v.getClass().getSimpleName(),
Toast.LENGTH_LONG).show();
});
if (currentView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) currentView;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
printClickedViews(viewGroup.getChildAt(i));
}
}
}
...
Please note that even if you add/remove a new View
, your OnGlobalLayoutListener
will get notified, and that's good.
Limitations
The most obvious limitation is that setting a View.OnClickListener
will have to be reserved for tracking clicks only. However, you can always use OnTouchListener
for the same purpose as follows:
view.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
// handle your click event here
}
return false;
});