首页 > 代码库 > Fragment切换动画

Fragment切换动画

题外话:

如何把一个 “小view” 或者 “小fragment” 覆盖到一个 “全屏view” 之上(见下图)。

方法一(FrameLayout + layout_marginTop ):

<FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
      <fragment
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</FrameLayout>

方法二(RelativeLayout + layout_alignParentBottom):

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
      <fragment
            android:layout_alignParentBottom="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</RelativeLayout>

 

开始正题,首先说一下为什么用Fragment而不用ViewGroup,我觉得Fragment是一个小的执行单元,它既有Actvity处理事件的能力又有ViewGroup inflate 局部显示的功能,避免把一堆业务上不相关的控件和事件处理都写在一个Actvity里面,ViewGroup不包含任何事件处理也方便其他地方共用。

先说一下需求,由界面A 过渡到界面B,上面蓝色的区域不动,FragmentA 自上而下逐渐消失,FragmentB自下而上逐渐显示,(就是做了一个translationY动画)。

百度谷歌了“Fragment 切换动画”,发现都是setCustomAnimations来做的,这个动画要求必须是objectAnimator (属性动画)

 

Fragment fragment = Fragment.instantiate(context, fragmentName, fragmentArgs);
FragmentTransaction transaction = ((Activity) context).getFragmentManager().beginTransaction();
fragment.setArguments(fragmentArgs);
transaction.setCustomAnimations(R.anim.expand_to_top, R.anim.collapse_from_top);
transaction.replace(R.id.network_diagnostics_status_zone, fragment).commit();//切换
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator
        xmlns:android="<a href=http://www.mamicode.com/"http://schemas.android.com/apk/res/android" "="" style="color: rgb(50, 108, 166); text-decoration: none; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius:>
        android:duration="600"
        android:propertyName="translationY"
        android:valueFrom="0dp"
        android:valueTo="500dp"
        android:valueType="floatType" />
</set>

 

但是发现了一个问题,FramentA 开始做collapse_from_top动画的时候,竟然不是以A点作为(0,0)原点开始做动画的,而是以B点作为(0,0)作为原点,这就会导致FragmentA先跳到B点,然后再做下移动画。

这算不算google的bug呢?

解决方法其实也挺简单,就是把Fragment当作ViewGroup当作来用

<fragment 
       android:id="@+id/a"
       android:name="FragmentA"
       android:layout_alignParentBottom="true"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>
<fragment 
       android:id="@+id/b"
       android:name="FragmentB"
       android:layout_alignParentBottom="true"
       android:visibility="gone"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>

 

FragmentB 默认是View.gone. 

 

View a = getActivity().findViewById(R.id.a);
View b = getActivity().findViewById(R.id.b);
switchView(a,b,true); //a做下移动画 b做上移动动画。

 

注意,findViewById的参数是 fragment 的 id,返回值是Fragment的 inflate 的ViewGroup,这样我们就可以像操作view一样来给fragment做切换动画了。


也可以通过fragment.getView()获取根view然后做动画。


获取 xml  中的 fragment

Fragment ss = (Fragment) getActivity().getFragmentManager().findFragmentById(R.id.network_diagnostics_scanning_zone);

Fragment切换动画