Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show DialogFragment with animation growing from a point

I'm showing a DialogFragment when the user taps on a row in a ListView. I'd like to animate the showing of the dialog so that it grows from the center of the row. A similar effect can be seen when opening a folder from the launcher.

One idea that I've had is a combination of TranslateAnimation and ScaleAnimation. Is there another way?

like image 618
Edward Dale Avatar asked Nov 15 '12 17:11

Edward Dale


2 Answers

Being DialogFragment a wrapper for the Dialog class, you should set a theme to your base Dialog to get the animation you want:

public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener {     @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,         Bundle savedInstanceState)      {         return super.onCreateView(inflater, container, savedInstanceState);     }      @Override     public Dialog onCreateDialog(Bundle savedInstanceState)      {         // Set a theme on the dialog builder constructor!         AlertDialog.Builder builder =              new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );          builder           .setTitle( "Your title" )         .setMessage( "Your message" )         .setPositiveButton( "OK" , new DialogInterface.OnClickListener()              {                     @Override               public void onClick(DialogInterface dialog, int which) {               dismiss();                               }         });         return builder.create();     } } 

Then you just need to define the theme that will include your desired animation. In styles.xml add your custom theme:

<style name="MyCustomTheme" parent="@android:style/Theme.Panel">     <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item> </style>  <style name="MyAnimation.Window" parent="@android:style/Animation.Activity">      <item name="android:windowEnterAnimation">@anim/anim_in</item>     <item name="android:windowExitAnimation">@anim/anim_out</item> </style>     

Now add the animation files in the res/anim folder:

( the android:pivotY is the key )

anim_in.xml

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">     <scale         android:interpolator="@android:anim/linear_interpolator"         android:fromXScale="0.0"         android:toXScale="1.0"         android:fromYScale="0.0"         android:toYScale="1.0"         android:fillAfter="false"         android:startOffset="200"         android:duration="200"          android:pivotX = "50%"         android:pivotY = "-90%"     />     <translate         android:fromYDelta="50%"         android:toYDelta="0"         android:startOffset="200"         android:duration="200"     /> </set> 

anim_out.xml

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">     <scale         android:interpolator="@android:anim/linear_interpolator"         android:fromXScale="1.0"         android:toXScale="0.0"         android:fromYScale="1.0"         android:toYScale="0.0"         android:fillAfter="false"         android:duration="200"          android:pivotX = "50%"                 android:pivotY = "-90%"             />     <translate         android:fromYDelta="0"         android:toYDelta="50%"         android:duration="200"     /> </set> 

Finally, the tricky thing here is to get your animation grow from the center of each row. I suppose the row is filling the screen horizontally so, on one hand the android:pivotX value will be static. On the other hand, you can't modify the android:pivotY value programmatically.

What I suggest is, you define several animations each of which having a different percentage value on the android:pivotY attribute (and several themes referencing those animations). Then, when the user taps the row, calculate the Y position in percentage of the row on the screen. Knowing the position in percentage, assign a theme to your dialog that has the appropriate android:pivotY value.

It is not a perfect solution but could do the trick for you. If you don't like the result, then I would suggest forgetting the DialogFragment and animating a simple View growing from the exact center of the row.

Good luck!

like image 75
Xavi Gil Avatar answered Sep 29 '22 07:09

Xavi Gil


Check it out this code, it works for me

// 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:toXDelta="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; } 
like image 30
Kiran Babu Avatar answered Sep 29 '22 07:09

Kiran Babu