I have a problem where in a specific situation when I call setVisibility(GONE)
inside my custom view, its onVisibilityChanged
method doesn't get called and it actually doesn't hide the view although getVisibility()
returns 8
(or GONE
) afterwards.
Here is how I know the visibility changes but onVisibilityChanged is not called.
@Override protected void onVisibilityChanged(@NonNull View changedView, int visibility) { Log.i(LOG_TAG, "onVisibilityChanged: " + visibility); super.onVisibilityChanged(changedView, visibility); } @Override public void setVisibility(int visibility) { super.setVisibility(visibility); Log.i(LOG_TAG, "setVisibility: " + visibility); } public void hide(){ Log.i(LOG_TAG, "before hide visibility: " + getVisibility()); setVisibility(GONE); Log.i(LOG_TAG, "after hide visibility: " + getVisibility()); }
Normally when I call hide()
I see these lines in the log:
before hide visibility: 0
onVisibilityChanged: 8
setVisibility: 8
after hide visibility: 8
But in a spicific situation when I call hide()
I get these lines in the log and the view isn't hidden afterwards although getVisibility()
returns 8
:
before hide visibility: 0
setVisibility: 8
after hide visibility: 8
So when in general does this happen? When does setVisibility
not call onVisibilityChanged
?
Don't ask what my specific situation is. But please provide every general situation where this might happen.
3 Answers
Answers 1
It is called only when the view is attached in the hierarchy.
The call to setVisibility looks like this:
public void setVisibility(@Visibility int visibility) { setFlags(visibility, VISIBILITY_MASK); }
The setFlags
method is a long one where a bunch of different view properties are changed and handled, but the noticable part is this:
if ((changed & VISIBILITY_MASK) != 0) { // if visiblity changed... ... if (mAttachInfo != null) { // true if attached in view hierarchy dispatchVisibilityChanged(this, newVisibility); // onVisibilityChanged is called from here ...
So you will see your described behaviour on a view that's not attached to a fragment or activity.
Answers 2
you can use another way to solve this problem
create a method like this
private void stateCheck(View view){ if (view.getVisibility()==View.GONE){ // handle gone state }else if (view.getVisibility()==View.INVISIBLE){ // handle invisible state }else{ // handle other states } }
Answers 3
View.onVisibilityChanged
Called when the visibility of the view or an ancestor of the view has changed.
As this says, onVisibilityChanged
will only be called when visibility is changed.
public void hide(){ setVisibility(GONE); }
This will be called in two cases.
- When visibility is
VISIBLE
. - When visibility is
INVISIBLE
.
This will not be called if View visibility is already set to GONE.
Solution
So how can you capture all the events of visibility?
Override setVisibility
method in your custom view class. This method will be called every time visibility is called. Like below
public class CustomTextView extends AppCompatTextView { @Override public void setVisibility(int visibility) { super.setVisibility(visibility); System.out.println("CustomTextView.setVisibility " + visibility); } }
0 comments:
Post a Comment