Android Fragment切换动画

Fragment也可以添加切换动画,由于Fragment是在API 11中新引入的类,因此为了兼容性我们需要使用support-v4这个兼容包,在这种情况下我们可以通过FragmentTransition中的setCustomAnimations()方法来添加切换动画。

这个切换动画需要是View动画,之所以不能采用属性动画是因为属性动画也是API 11新引入的。

在res/anim目录创建动画:

  • fragment_enter_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true">

    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"/>

    <translate
        android:fromXDelta="100%"
        android:toXDelta="0"/>

</set>
  • fragment_exit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true">

    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"/>

    <translate
        android:fromXDelta="0"
        android:toXDelta="100%"/>

</set>
  • fragment_pop_enter_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true">

    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"/>

    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>

</set>
  • fragment_pop_exit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true">

    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />

    <rotate
        android:fromDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="0" />


</set>
  • Fragment代码
public class SwitchFragment extends Fragment {

    private AddBackStackListener listener;
    private Button button;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof AddBackStackListener) {
            listener = (AddBackStackListener) context;
        } else {
            throw new RuntimeException("activity must be implements AddBackStackListener!");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_switch, container, false);
        button = view.findViewById(R.id.btn_add_fragment);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    listener.addBackStack(new SwitchFragment());
                }
            }
        });
    }
}
  • Activity代码
public class FragmentSwitchActivity extends AppCompatActivity implements AddBackStackListener {

    private Button button;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_switch);

        button = findViewById(R.id.btn_switch_fragment);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                addToBackStack(new SwitchFragment());
                button.setVisibility(View.GONE);
            }
        });
    }

    /**
     *  fragment回调接口,添加Fragment到栈中
     */
    @Override
    public void addBackStack(Fragment fragment) {
        addToBackStack(fragment);
    }

    private void addToBackStack(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // 系统提供的Fragment切换动画
        // FragmentTransaction.TRANSIT_FRAGMENT_FADE: 淡入效果
        // FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
        // FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
        // FragmentTransaction.TRANSIT_ENTER_MASK:
        // FragmentTransaction.TRANSIT_EXIT_MASK:
        // FragmentTransaction.TRANSIT_NONE:
        // FragmentTransaction.TRANSIT_UNSET:

//      transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

//      transaction.setCustomAnimations(R.anim.fragment_enter_anim, R.anim.fragment_exit_anim);
        // 加入Fragment压栈和弹栈动画
        // 存在的问题:Fragment压栈的动画R.anim.pop_enter_anim没有执行,压栈都是执行fragment_enter_anim
        transaction.setCustomAnimations(R.anim.fragment_enter_anim, R.anim.fragment_exit_anim,
                R.anim.fragment_pop_enter_anim, R.anim.fragment_pop_eixt_anim);
        transaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
        transaction.commit();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            onBackPressed();
        }
        return true;
    }

    @Override
    public void onBackPressed() {
        fragmentPopStack();
    }

    private void fragmentPopStack() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Log.i("FragmentSwitchActivity", fragmentManager.getBackStackEntryCount() + "");
        if (fragmentManager.getBackStackEntryCount() > 0) {
            // 这里的Fragment弹栈会有指定的R.anim.fragment_pop_exit_anim.xml动画效果
            fragmentManager.popBackStack();

            if (fragmentManager.getBackStackEntryCount() == 1) {
                button.setVisibility(View.VISIBLE);
            }

        } else {
            finish();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值