Fragment transaction animation: slide in and slide out

前端 未结 6 1430
梦谈多话
梦谈多话 2020-11-27 09:44

I\'ve check some tutorials for animate transaction between fragments. I\'ve used this method for animation and it works:

fragmentTransaction.setCustomAnimatio         


        
相关标签:
6条回答
  • 2020-11-27 09:58

    UPDATE For Android v19+ see this link via @Sandra

    You can create your own animations. Place animation XML files in res > anim

    enter_from_left.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
      <translate 
          android:fromXDelta="-100%p" android:toXDelta="0%"
          android:fromYDelta="0%" android:toYDelta="0%"
          android:duration="@android:integer/config_mediumAnimTime"/>
    </set>
    

    enter_from_right.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
      <translate
         android:fromXDelta="100%p" android:toXDelta="0%"
         android:fromYDelta="0%" android:toYDelta="0%"
         android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    exit_to_left.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
      <translate 
          android:fromXDelta="0%" android:toXDelta="-100%p"
          android:fromYDelta="0%" android:toYDelta="0%"
          android:duration="@android:integer/config_mediumAnimTime"/>
    </set>
    

    exit_to_right.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
      <translate
         android:fromXDelta="0%" android:toXDelta="100%p"
         android:fromYDelta="0%" android:toYDelta="0%"
         android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    you can change the duration to short animation time

    android:duration="@android:integer/config_shortAnimTime"
    

    or long animation time

    android:duration="@android:integer/config_longAnimTime" 
    

    USAGE (note that the order in which you call methods on the transaction matters. Add the animation before you call .replace, .commit):

    FragmentTransaction transaction = supportFragmentManager.beginTransaction();
    transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
    transaction.replace(R.id.content_frame, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
    
    0 讨论(0)
  • 2020-11-27 10:01

    This is another solution which I use:

    public class CustomAnimator {
        private static final String TAG = "com.example.CustomAnimator";
    
        private static Stack<AnimationEntry> animation_stack    = new Stack<>();
    
        public static final int                 DIRECTION_LEFT  = 1;
        public static final int                 DIRECTION_RIGHT = -1;
        public static final int                 DIRECTION_UP    = 2;
        public static final int                 DIRECTION_DOWN  = -2;
    
        static class AnimationEntry {
            View in;
            View    out;
            int     direction;
            long    duration;
        }
    
        public static boolean hasHistory() {
            return !animation_stack.empty();
        }
    
        public static void reversePrevious() {
            if (!animation_stack.empty()) {
                AnimationEntry entry = animation_stack.pop();
                slide(entry.out, entry.in, -entry.direction, entry.duration, false);
            }
        }
    
        public static void clearHistory() {
            animation_stack.clear();
        }
    
        public static void slide(final View in, View out, final int direction, long duration) {
            slide(in, out, direction, duration, true);
        }
    
        private static void slide(final View in, final View out, final int direction, final long duration, final boolean save) {
    
            ViewGroup in_parent = (ViewGroup) in.getParent();
            ViewGroup out_parent = (ViewGroup) out.getParent();
    
            if (!in_parent.equals(out_parent)) {
                return;
            }
    
            int parent_width = in_parent.getWidth();
            int parent_height = in_parent.getHeight();
    
            ObjectAnimator slide_out;
            ObjectAnimator slide_in;
    
            switch (direction) {
                case DIRECTION_LEFT:
                default:
                    slide_in = ObjectAnimator.ofFloat(in, "translationX", parent_width, 0);
                    slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, -out.getWidth());
                    break;
                case DIRECTION_RIGHT:
                    slide_in = ObjectAnimator.ofFloat(in, "translationX", -out.getWidth(), 0);
                    slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, parent_width);
                    break;
                case DIRECTION_UP:
                    slide_in = ObjectAnimator.ofFloat(in, "translationY", parent_height, 0);
                    slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, -out.getHeight());
                    break;
                case DIRECTION_DOWN:
                    slide_in = ObjectAnimator.ofFloat(in, "translationY", -out.getHeight(), 0);
                    slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, parent_height);
                    break;
            }
    
            AnimatorSet animations = new AnimatorSet();
            animations.setDuration(duration);
            animations.playTogether(slide_in, slide_out);
            animations.addListener(new Animator.AnimatorListener() {
    
                @Override
                public void onAnimationCancel(Animator arg0) {
                }
    
                @Override
                public void onAnimationEnd(Animator arg0) {
                    out.setVisibility(View.INVISIBLE);
                    if (save) {
                        AnimationEntry ae = new AnimationEntry();
                        ae.in = in;
                        ae.out = out;
                        ae.direction = direction;
                        ae.duration = duration;
                        animation_stack.push(ae);
                    }
                }
    
                @Override
                public void onAnimationRepeat(Animator arg0) {
                }
    
                @Override
                public void onAnimationStart(Animator arg0) {
                    in.setVisibility(View.VISIBLE);
                }
            });
            animations.start();
        }
    }
    

    The usage of class. Let's say you have two fragments (list and details fragments)as shown below

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ui_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <FrameLayout
            android:id="@+id/list_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <FrameLayout
            android:id="@+id/details_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </FrameLayout>
    

    Usage

    View details_container = findViewById(R.id.details_container);
    View list_container = findViewById(R.id.list_container);
    // You can select the direction left/right/up/down and the duration
    CustomAnimator.slide(list_container, details_container,CustomAnimator.DIRECTION_LEFT, 400);
    

    You can use the function CustomAnimator.reversePrevious();to get the previous view when the user pressed back.

    0 讨论(0)
  • 2020-11-27 10:07

    I have same issue, i used simple solution

    1)create sliding_out_right.xml in anim folder

      <?xml version="1.0" encoding="utf-8"?>
        <set xmlns:android="http://schemas.android.com/apk/res/android">
            <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
            <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
        </set>
    

    2) create sliding_in_left.xml in anim folder

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    3) simply using fragment transaction setCustomeAnimations() with two custom xml and two default xml for animation as follows :-

     fragmentTransaction.setCustomAnimations(R.anim.sliding_in_left, R.anim.sliding_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right );
    
    0 讨论(0)
  • 2020-11-27 10:07

    slide_in_down.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="@android:integer/config_longAnimTime"
            android:fromYDelta="0%p"
            android:toYDelta="100%p" />
    </set>
    

    slide_in_up.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="@android:integer/config_longAnimTime"
            android:fromYDelta="100%p"
            android:toYDelta="0%p" />
    </set>
    

    slide_out_down.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="@android:integer/config_longAnimTime"
            android:fromYDelta="-100%"
            android:toYDelta="0"
            />
    </set>
    

    slide_out_up.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="@android:integer/config_longAnimTime"
            android:fromYDelta="0%p"
            android:toYDelta="-100%p"
            />
    </set>
    

    direction = down

                activity.getSupportFragmentManager()
                        .beginTransaction()
                        .setCustomAnimations(R.anim.slide_out_down, R.anim.slide_in_down)
                        .replace(R.id.container, new CardFrontFragment())
                        .commit();
    

    direction = up

               activity.getSupportFragmentManager()
                        .beginTransaction()
                        .setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up)
                        .replace(R.id.container, new CardFrontFragment())
                        .commit();
    
    0 讨论(0)
  • 2020-11-27 10:19

    There is three way to transaction animation in fragment.

    Transitions

    So need to use one of the built-in Transitions, use the setTranstion() method:

    getSupportFragmentManager()
            .beginTransaction()
            .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_OPEN )
            .show( m_topFragment )
            .commit()
    

    Custom Animations

    You can also customize the animation by using the setCustomAnimations() method:

    getSupportFragmentManager()
            .beginTransaction()
            .setCustomAnimations( R.anim.slide_up, 0, 0, R.anim.slide_down)
            .show( m_topFragment )
            .commit()
    

    slide_up.xml

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:propertyName="translationY"
            android:valueType="floatType"
            android:valueFrom="1280"
            android:valueTo="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
    

    slide_down.xml

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:propertyName="translationY"
            android:valueType="floatType"
            android:valueFrom="0"
            android:valueTo="1280"
            android:duration="@android:integer/config_mediumAnimTime"/>
    

    Multiple Animations

    Finally, It's also possible to kick-off multiple fragment animations in a single transaction. This allows for a pretty cool effect where one fragment is sliding up and the other slides down at the same time:

    getSupportFragmentManager()
            .beginTransaction()
            .setCustomAnimations( R.anim.abc_slide_in_top, R.anim.abc_slide_out_top ) // Top Fragment Animation
            .show( m_topFragment )
            .setCustomAnimations( R.anim.abc_slide_in_bottom, R.anim.abc_slide_out_bottom ) // Bottom Fragment Animation
            .show( m_bottomFragment )
            .commit()
    

    To more detail you can visit URL

    Note:- You can check animation according to your requirement because above may be have issue.

    0 讨论(0)
  • 2020-11-27 10:21

    Have the same problem with white screen during transition from one fragment to another. Have navigation and animations set in action in navigation.xml.

    Background in all fragments the same but white blank screen. So i set navOptions in fragment during executing transition

              //Transition options
            val options = navOptions {
                anim {
                    enter = R.anim.slide_in_right
                    exit = R.anim.slide_out_left
                    popEnter = R.anim.slide_in_left
                    popExit = R.anim.slide_out_right
                }
            }
    
    .......................
    
      this.findNavController().navigate(SampleFragmentDirections.actionSampleFragmentToChartFragment(it),
                        options)
    

    It worked for me. No white screen between transistion. Magic )

    0 讨论(0)
提交回复
热议问题