Android Visibility from GONE to VISIBLE not working the first time
Hello I have a problem with animation I am trying to do.
I am using this AndroidViewAnimations library .
Here is my layout XML:
<Button
android:id="@+id/buttonDetails"
style="@style/Button_Details"/>
<LinearLayout
android:id="@+id/linearLayoutDetails"
android:visibility="gone"
style="@style/LinearLayout_Details">
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clmn_text"
android:checked="true"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clme_text"
android:checked="true"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clmn_text"
android:checked="true"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clmn_text"
android:checked="true"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clmn_text"
android:checked="true"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_clmn_text"
android:checked="true"/>
</LinearLayout>
And here is my Java code:
// Declare Variables
@ViewById
LinearLayout linearLayoutDetails;
@Click
void buttonDetails() {
// Checks Linear Layout Visibility
if (linearLayoutDetails.getVisibility() == View.GONE) {
// Sets linearLayoutDetails Visibility to VISIBLE
linearLayoutDetails.setVisibility(View.VISIBLE);
// Makes Appear Animation
YoYo.with(Techniques.SlideInDown)
.duration(700)
.playOn(linearLayoutDetails);
} else {
linearLayoutDetails.setVisibility(View.GONE);
}
}
Now the problem is that the first time I click the button the animation doesn't work, but after that it works every time.
I did some research and I found that the problem is that I have the visibility to be removed and if I set it to invisible it works great the first time. The thing is, I don't want the visibility to be invisible but is gone because I don't want the linear layout to take up space when it's hidden.
Any ideas?
source to share
I just solved it a couple of minutes ago using ViewTreeObserver. In the example below, the variable currentMode
is the view that I want to animate and render. Its default is "gone" and I had the EXACT problem you are facing.
This is how I solved it:
ViewTreeObserver vto = currentMode.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if(currentMode.isShown()) {
YoYo.with(Techniques.SlideInDown).duration(250).playOn(currentMode);
}
}
});
currentMode.setVisibility(mShouldShowMode ? View.VISIBLE : View.GONE);
Using the ViewTreeObserver, we can observe global changes in the user interface and then react. The method View.isShown()
checks if its visible. If so, then I start the animation. This works great for me.
Then, to animate the exit, you need to attach a listener to the exit animation like this:
YoYo.with(Techniques.SlideOutUp).duration(250).withListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
currentMode.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}).playOn(currentMode);
source to share
workaround:
boolean firstTIme = true;
(...)
@Click
void buttonDetails() {
// Checks Linear Layout Visibility
if (linearLayoutDetails.getVisibility() == View.GONE || firstTIme) {
firstTIme = false;
linearLayoutDetails.setVisibility(View.VISIBLE);
YoYo.with(Techniques.SlideInDown)
.duration(700)
.playOn(linearLayoutDetails);
} else {
linearLayoutDetails.setVisibility(View.GONE);
}
}
source to share
If you are using YoYo Library try this.
YoYo.with(Techniques.SlideInDown)
.duration(400)
.withListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
//this will do the trick
YoYo.with(Techniques.Landing)
.duration(1)
.playOn(view);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
})
.playOn(view);
You can also use this to animate continuously on any view object.
source to share
I had a similar problem and even with the accepted answer, I couldn't get it to work. So I did this
TransitionInflater inflater = TransitionInflater.from(context);
Transition transition = inflater.inflateTransition(R.transition.yoyo_transition);
transition.addListener(new Transition.TransitionListener() {
...
@Override
public void onTransitionEnd(Transition transition) {
do_stuff_with_yoyo();
}
...
});
TransitionManager.beginDelayedTransition((ViewGroup) getRootView(), transition);
yoyo.setVisibility(View.VISIBLE);
yoyo_transition.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds android:duration="0">
<targets>
<target android:targetId="@+id/yoyo_id"></target>
</targets>
</changeBounds>
<fade android:duration="0">
<targets>
<target android:targetId="@+id/yoyo_id"></target>
</targets>
</fade>
</transitionSet>
source to share