Android -- Activity,Fragment切換動畫。

前言:Activity和Fragment的切換動畫在開發中使用並不是很多,但是在一些特殊頁面,如:微信的WXPayEntryActivity中,透明關閉,就需要對Activity的切換動畫進行處理。

效果圖
這裏寫圖片描述

目錄

  • Activity切換動畫
  • Activity共享元素動畫
  • Fragment切換動畫
  • 使用Style控制Activity全局切換動畫

Activity切換動畫

這裏寫圖片描述

OneActivity

    @OnClick(R.id.btn_to_two)
    public void onViewClicked() {
        Intent mIntent = new Intent(OneActivity.this,TwoActivity.class);
        startActivity(mIntent);
        overridePendingTransition(R.anim.enter_scale,0);
    }

enter_scale

<set xmlns:android="http://schemas.android.com/apk/res/android"
   >
    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="0"
        android:fromYScale="0"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:duration="1000"
        />

</set>

OneActivity設置了一箇中心點爲屏幕中央,從小到大的縮放動畫。

TwoActivity

 @Override
    public void finish() {
        super.finish();
        overridePendingTransition(0, R.anim.exit_scale);
    }

exit_scale

<set xmlns:android="http://schemas.android.com/apk/res/android"
   >
    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="0"
        android:toYScale="0"
        android:duration="500"
        />

</set>

TwoActivity 重寫了finish方法,在調用finish方法後面添加了overridePendingTransition()方法,給TwoActivity添加一個關閉動畫。

ps:這裏寫成overridePendingTransition(0, R.anim.exit_scale);方式是因爲用模擬器使用當前Activity(View)放大(縮小),切換的Activity(View)放大(縮小),會有一幀幀的影像,具體原因我沒深究,在真機上是OK的,爲了gif圖片效果,所以這裏我就去掉了一個動畫(有興趣可以自行添加上試試)。

overridePendingTransition (int enterAnim, int exitAnim)關鍵在於這個方法;
這個方法是Android 2.0開始在Activity增加的一個方法;
其中
- enterAnim 定義Activity進入屏幕時的動畫
- exitAnim 定義Activity退出屏幕時的動畫

注意:overridePendingTransition 方法必須在startActivity()或者 finish()方法的後面。

通俗來說就是enterAnim動畫效果對應切換的Activity的View,exitAnim對應就是當前的Activity的View。
而定義anim的文件可以是set 這意味着可以添加一個組合動畫。
我把enter_scale添加一個動畫
這裏寫圖片描述

enter_scale

<set xmlns:android="http://schemas.android.com/apk/res/android"
   >
    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="0"
        android:fromYScale="0"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:duration="1000"
        />

    <rotate
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromDegrees="0"
        android:toDegrees="-360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000"/>

</set>

可以看見···如ps上所說的效果~ !!
可以看見,一箇中心放大並且旋轉的切換動畫就出來了。

Activity共享元素動畫

共享元素動畫是LOLLIPOP之後才增加的效果。
這裏寫圖片描述

這裏寫圖片描述

TwoActivity

public class TwoActivity extends AppCompatActivity {

    @Bind(R.id.btn_to_one)
    Button btnToOne;

    @Bind(R.id.sharedView)
    View mView;

    @Bind(R.id.img_view)
    ImageView imgView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_two);
        getSupportActionBar().setTitle("TwoActivity");
        ButterKnife.bind(this);

        String url = "http://imgsrc.baidu.com/imgad/pic/item/caef76094b36acaf0accebde76d98d1001e99ce7.jpg";

        Glide.with(this).load(url).into(imgView);
    }


    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(0, R.anim.exit_scale);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @OnClick({R.id.sharedView, R.id.img_view,R.id.btn_to_one})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.sharedView:
                Intent mIntent1 = new Intent(TwoActivity.this, ThreeActivity.class);
                ActivityOptions options1 = ActivityOptions
                        .makeSceneTransitionAnimation(TwoActivity.this, view, "sharedView");

                ActivityCompat.startActivity(TwoActivity.this, mIntent1, options1.toBundle());
                break;
            case R.id.img_view:
                Intent mIntent2 = new Intent(TwoActivity.this, ThreeActivity.class);
                ActivityOptions options2 = ActivityOptions
                        .makeSceneTransitionAnimation(TwoActivity.this, view, "sharedImage");

                ActivityCompat.startActivity(TwoActivity.this, mIntent2, options2.toBundle());
                break;
            case R.id.btn_to_one:

   Pair first = new Pair<>(mView, ViewCompat.getTransitionName(mView));
                Pair second = new Pair<>(imgView, ViewCompat.getTransitionName(imgView));

                ActivityOptionsCompat transitionActivityOptions =
                        ActivityOptionsCompat.makeSceneTransitionAnimation(this, first, second);
                Intent mIntent = new Intent(TwoActivity.this, ThreeActivity.class);
                ActivityCompat.startActivity(TwoActivity.this, mIntent, transitionActivityOptions.toBundle());
                break;
        }
    }
}

activity_two

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blueviolet"
    tools:context="norton.animademo.activitytransformer.TwoActivity">

    <Button
        android:id="@+id/btn_to_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="to_one"
        />

    <View
        android:id="@+id/sharedView"
        android:layout_below="@+id/btn_to_one"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/lawngreen"
        android:transitionName="sharedView" />

    <ImageView
        android:id="@+id/img_view"
        android:layout_below="@+id/sharedView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="10dp"
        android:transitionName="sharedImage"
        />

</RelativeLayout>

共享元素動畫可以是單個元素也可以是一個集合,如果是單個則需要設置android:transitionName=”sharedImage” 屬性,如果是多個則需要使用Pair對象。

注意: 共享元素動畫也是可以自定義的大致的操作步驟是繼承ChangeBounds,重寫createAnimator方法;不過這種使用情況太少,我就沒有深究了。

Fragment切換動畫

這裏寫圖片描述

FragmentTransformerActivity

@Bind(R.id.fragment)
    FrameLayout fragment;


    private OneFragment oneFragment;
    private TwoFragment twoFragment;


    public static void startAction(Context context) {
        Intent mIntent = new Intent(context, FragmentTransformerActivity.class);
        context.startActivity(mIntent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_transformer);
        ButterKnife.bind(this);
        getSupportActionBar().setTitle("FragmentTransformerActivity");

        oneFragment = new OneFragment();
        twoFragment = new TwoFragment();

        setOneFragment();
    }

    private void setOneFragment() {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        ft.setCustomAnimations(R.anim.enter_scale,R.anim.exit_scale);
        ft.replace(R.id.fragment, oneFragment);
        ft.commit();

    }


    private void setTwoFragment() {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        ft.setCustomAnimations(R.anim.enter_scale,R.anim.exit_scale);
        ft.replace(R.id.fragment, twoFragment);
        ft.commit();
    }



    @OnClick({R.id.btn_one, R.id.btn_two})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_one:
                setOneFragment();
                break;
            case R.id.btn_two:
                setTwoFragment();
                break;
        }
    }
}

xml比較簡單就不貼了,anim見Activity的enter_scale;
偷了個懶Fragment我就直接new出來了,沒有使用官方推薦寫法。
這裏主要看setCustomAnimations方法,Fragment切換動畫的方法和Activity的很相似,第一個是進入動畫,退出動畫。

注意:使用v4包下的Fragment(我使用app下的Fragment添加切換效果各種bug~)。

使用Style控制Activity全局切換動畫

這裏寫圖片描述

   <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <item name="android:windowAnimationStyle">@style/transformer</item>
    </style>

    <style name="transformer" parent="@android:style/Animation.Activity">
        <item name="android:activityOpenEnterAnimation">@anim/enter_right</item>
        <item name="android:activityOpenExitAnimation">@anim/exit_left</item>
        <item name="android:activityCloseEnterAnimation">@anim/enter_left</item>
        <item name="android:activityCloseExitAnimation">@anim/exit_right</item>
    </style>

這個相信很多人都用過,只需要在style下重新配置Animation.Activity的打開和關閉動畫就好了。

總結:切換動畫的使用還是比較簡單的,還是那句話難點在動畫,而且,數學要好!數學要好!數學要好!

源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章