Change DialogFragment enter/exit transition at just before dismissing
I have a DialogFragment
and I set animation for enter/exit in the onActivityCreated
method as below:
@Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimation;
}
My DialogAnimation
style files is as follows:
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style>
This works for me now...
Now my problem is i want to have two different exit animation one for when the "OK" button is clicked and one for the cancel button. So what I did was I tried changing the transition just before dismissing but it didn't work.
Any solution on how it can be achieved?
This is what I tried:
@Override
public void onClick(View v) {
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimation2;
this.dismiss();
}
Solution 1:
You can do it inside your DialogFragment, without changing
getDialog().getWindow()
.getAttributes().windowAnimations
You should animate "decor view" in onStart and onClick.
This is the code snipped :
Create Dialog first
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle("Hello from animated dialog :)")
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//we have to add button here and then override it's click in onStart
}
}
)
.setCancelable(false)
.create();
}
Then override onStart method
@Override
public void onStart() {
super.onStart();
AlertDialog dialog = (AlertDialog)getDialog();
final View decorView = getDialog()
.getWindow()
.getDecorView();
ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
PropertyValuesHolder.ofFloat("scaleX", 0.0f, 1.0f),
PropertyValuesHolder.ofFloat("scaleY", 0.0f, 1.0f),
PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f));
scaleDown.setDuration(2000);
scaleDown.start();
Button positiveButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
positiveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
final View decorView = getDialog()
.getWindow()
.getDecorView();
ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f),
PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f),
PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f));
scaleDown.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
dismiss();
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
scaleDown.setDuration(2000);
scaleDown.start();
}
});
}
Here is the result animation
And if you remove scale properties from my code you will get only alpha animation. Exactly as you wanted.
Remove this:
PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f),
PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f),
Solution 2:
You can set an Up & Down animations for dialog fragment. In 'res/anim' add two files:
// Slide up animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="100%"
android:interpolator="@android:anim/accelerate_interpolator"
android:toYDelta="0" />
</set>
// Slide dowm animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="0%p"
android:interpolator="@android:anim/accelerate_interpolator"
android:toYDelta="100%p" />
</set>
// Style
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">@anim/slide_up</item>
<item name="android:windowExitAnimation">@anim/slide_down</item>
</style>
// Inside Dialog Fragment
@Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimation;
}
Solution 3:
I think the best approach is to call the different animations on Button click. Hence you would have something similar to the below:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button OkButton = (Button) findViewById(R.id.btnOk);
Button CancelButton = (Button) findViewById(R.id.btnCancel);
OkButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
}
});
return true;
CancelButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimation2;
}
});
return true;
}
If I were you, I would also use correct naming conventions for future reference. For example setting DialogAnimation to OkAnimation and DialogAnimation2 to CancelAnimation.
Home this helps :)
Solution 4:
One simple way to do what you want is to use animation listeners like.
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
// dismiss your dialog in here and it will work
}
});
Start animation on your onclick method and dismiss dialog on onAnimationEnd() method.You may have to make snimation objects and start them manually with View's startAnimation(animation) method.