Is there a way to handle a view visibility change (say, from GONE to VISIBLE) without overriding the view?
Something like View.setOnVisibilityChangeListener();?
Is there a way to handle a view visibility change (say, from GONE to VISIBLE) without overriding the view?
Something like View.setOnVisibilityChangeListener();?
You can use a GlobalLayoutListener to determine if there are any changes in the views visibility.
myView.setTag(myView.getVisibility());
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int newVis = myView.getVisibility();
if((int)myView.getTag() != newVis)
{
myView.setTag(myView.getVisibility());
//visibility has changed
}
}
});
Instead of subclassing you can use decoration:
class WatchedView {
static class Listener {
void onVisibilityChanged(int visibility);
}
private View v;
private Listener listener;
WatchedView(View v) {
this.v = v;
}
void setListener(Listener l) {
this.listener = l;
}
public setVisibility(int visibility) {
v.setVisibility(visibility);
if(listener != null) {
listener.onVisibilityChanged(visibility);
}
}
}
Then
WatchedView v = new WatchedView(findViewById(R.id.myview));
v.setListener(this);
Take a look at ViewTreeObserver.OnGlobalLayoutListener. As written in documentation, its callback method onGlobalLayout() is invoked when the global layout state or the visibility of views within the view tree changes. So you can try to use it to detect when view visibility changes.
Kotlin seems to be much easier if anyone needs that. Using a similar approach as the accepted answer will work as well (setting a tag) if you needed to tracking coming from invisible but I used this for GONE -> VISIBLE -> GONE
binding.myView.viewTreeObserver.addOnGlobalLayoutListener {
when (binding.myView.visibility) {
View.VISIBLE -> {
}
View.GONE -> {
}
}
}