ActivityOptionsCompat--Material Designer的低版本兼容實現

本文是對API中的方法做了介紹,如果想要看如何讓這些方法兼容4.x或2.x可以看這篇文章:

 用開源項目ActivityOptionsICS讓ActivityOptions的動畫實現兼容

新版的V4包中有了這個類—— ActivityOptionsCompat,我們可以通過這個類來啓動activity和添加動畫。但不幸的是所有的動畫都沒有給2.x用的,大部分動畫也對4.x不兼容。我們就來看看是否讓低版本也兼容這些動畫效果。

好消息是這個類是兼容2.x的,通過這個類編寫的嗲嗎,雖然不能給2.x帶來動畫,但也能確保全版本穩定運行,不會需要我們判斷版本。也就是說如果你給5.x平臺做了動畫,其他平臺雖然不會執行動畫,但仍舊可以穩定打開activity。下面我們通過遠嗎進行分析下這個類。

1.文檔解釋

(1)ActivityOptionsCompat.makeCustomAnimation(context, enterResId, exitResId)

簡單做一個定製的動畫,這個參數很簡單,傳入一個進入的動畫的id,和移除動畫的id即可

複製代碼
        //讓新的Activity從一個小的範圍擴大到全屏
        ActivityOptionsCompat options = 
                ActivityOptionsCompat.makeCustomAnimation(this, 
                        R.anim.slide_bottom_in, R.anim.slide_bottom_out);
        startNewAcitivity(options);
複製代碼
複製代碼
    
    private void startNewAcitivity(ActivityOptionsCompat options) {
        Intent intent = new Intent(this,DetailActivity.class);  
        ActivityCompat.startActivity(this, intent, options.toBundle());  
    }
複製代碼

這個我感覺沒什麼用處,類似於

        Intent intent = new Intent(this,DetailActivity.class);  
        startActivity(intent);

        overridePendingTransition(R.anim.slide_bottom_in, android.R.anim.fade_out);

還不如直接用這個全版本的overridePendingTransition呢

 

(2)ActivityOptionsCompat.makeScaleUpAnimation(source, startX, startY, startWidth, startHeight)

這個在4.x上有用,可以實現新的Activity從某個固定的座標以某個大小擴大至全屏,我覺得效果挺不錯的。

這個新Activity就是從根據那個圖片的座標來拉伸展示的,對於相冊是很好的展示效果。

複製代碼
private void scaleUpAnimation(View view) {
        //讓新的Activity從一個小的範圍擴大到全屏
        ActivityOptionsCompat options = 
                ActivityOptionsCompat.makeScaleUpAnimation(view, //The View that the new activity is animating from
                        (int)view.getWidth()/2, (int)view.getHeight()/2, //拉伸開始的座標
                        0, 0);//拉伸開始的區域大小,這裏用(0,0)表示從無到全屏
        startNewAcitivity(options);
    }
複製代碼
    private void startNewAcitivity(ActivityOptionsCompat options) {
        Intent intent = new Intent(this,DetailActivity.class);  
        ActivityCompat.startActivity(this, intent, options.toBundle());  
    }

 

(3)ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElement, sharedElementName)

當你需要當前界面中的某個元素和新界面中的元素有關時,你可以使用這個動畫。效果很贊~!

這個圖片就是通過動畫和上一個界面的圖片進行了聯繫。

要使用這個方法就必須給兩個不同Activity的中的佈局元素設定同樣的一個android:transitionName,然後還需要一個標誌來告訴Window執行動畫,因爲這個只是在5.x上有效,不是本文的討論範圍。詳細看官方文檔即可。

標誌:etWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

也可以參考文章:

http://blog.csdn.net/a396901990/article/details/40187203

http://blog.jobbole.com/77015/

 

(4)ActivityOptionsCompat.makeSceneTransitionAnimation((Activity arg0, Pair<View, String>...  arg1)

這個方法用於多個元素和新的Activity相關的情況,注意下第二個參數Pair這個鍵值對後面有...,標明是可以傳入多個Pair對象的。

 

(5)ActivityOptionsCompat.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY)

這個方法可以用於4.x上,是將一個小塊的Bitmpat進行拉伸的動畫。

詳細使用方式,參考官方文檔:https://developer.android.com/training/material/animations.html

 

2.源碼

看完了文檔,心裏各種淒涼。很多優秀的動畫都不向下兼容,那麼我們去源碼中看看我們的主流4.x版本能用上什麼。

複製代碼
public class ActivityOptionsCompat {
    /**
     * Create an ActivityOptions specifying a custom animation to run when the
     * activity is displayed.
     *
     * @param context Who is defining this. This is the application that the
     * animation resources will be loaded from.
     * @param enterResId A resource ID of the animation resource to use for the
     * incoming activity. Use 0 for no animation.
     * @param exitResId A resource ID of the animation resource to use for the
     * outgoing activity. Use 0 for no animation.
     * @return Returns a new ActivityOptions object that you can use to supply
     * these options as the options Bundle when starting an activity.
     */
    public static ActivityOptionsCompat makeCustomAnimation(Context context,
            int enterResId, int exitResId) {
        if (Build.VERSION.SDK_INT >= 16) {
            return new ActivityOptionsImplJB(
                ActivityOptionsCompatJB.makeCustomAnimation(context, enterResId, exitResId));
        }
        return new ActivityOptionsCompat();
    }

    /**
     * Create an ActivityOptions specifying an animation where the new activity is
     * scaled from a small originating area of the screen to its final full
     * representation.
     * <p/>
     * If the Intent this is being used with has not set its
     * {@link android.content.Intent#setSourceBounds(android.graphics.Rect)},
     * those bounds will be filled in for you based on the initial bounds passed
     * in here.
     *
     * @param source The View that the new activity is animating from. This
     * defines the coordinate space for startX and startY.
     * @param startX The x starting location of the new activity, relative to
     * source.
     * @param startY The y starting location of the activity, relative to source.
     * @param startWidth The initial width of the new activity.
     * @param startHeight The initial height of the new activity.
     * @return Returns a new ActivityOptions object that you can use to supply
     * these options as the options Bundle when starting an activity.
     */
    public static ActivityOptionsCompat makeScaleUpAnimation(View source,
            int startX, int startY, int startWidth, int startHeight) {
        if (Build.VERSION.SDK_INT >= 16) {
            return new ActivityOptionsImplJB(
                ActivityOptionsCompatJB.makeScaleUpAnimation(source, startX, startY,
                        startWidth, startHeight));
        }
        return new ActivityOptionsCompat();
    }

    /**
     * Create an ActivityOptions specifying an animation where a thumbnail is
     * scaled from a given position to the new activity window that is being
     * started.
     * <p/>
     * If the Intent this is being used with has not set its
     * {@link android.content.Intent#setSourceBounds(android.graphics.Rect)},
     * those bounds will be filled in for you based on the initial thumbnail
     * location and size provided here.
     *
     * @param source The View that this thumbnail is animating from. This
     * defines the coordinate space for startX and startY.
     * @param thumbnail The bitmap that will be shown as the initial thumbnail
     * of the animation.
     * @param startX The x starting location of the bitmap, relative to source.
     * @param startY The y starting location of the bitmap, relative to source.
     * @return Returns a new ActivityOptions object that you can use to supply
     * these options as the options Bundle when starting an activity.
     */
    public static ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source,
            Bitmap thumbnail, int startX, int startY) {
        if (Build.VERSION.SDK_INT >= 16) {
            return new ActivityOptionsImplJB(
                ActivityOptionsCompatJB.makeThumbnailScaleUpAnimation(source, thumbnail,
                        startX, startY));
        }
        return new ActivityOptionsCompat();
    }
複製代碼

 

複製代碼
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support.v4.app;

import android.app.ActivityOptions;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;

class ActivityOptionsCompatJB {

    public static ActivityOptionsCompatJB makeCustomAnimation(Context context,
            int enterResId, int exitResId) {
        return new ActivityOptionsCompatJB(
            ActivityOptions.makeCustomAnimation(context, enterResId, exitResId));
    }

    public static ActivityOptionsCompatJB makeScaleUpAnimation(View source,
            int startX, int startY, int startWidth, int startHeight) {
        return new ActivityOptionsCompatJB(
            ActivityOptions.makeScaleUpAnimation(source, startX, startY, startWidth, startHeight));
    }

    public static ActivityOptionsCompatJB makeThumbnailScaleUpAnimation(View source,
            Bitmap thumbnail, int startX, int startY) {
        return new ActivityOptionsCompatJB(
            ActivityOptions.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY));
    }

    private final ActivityOptions mActivityOptions;

    private ActivityOptionsCompatJB(ActivityOptions activityOptions) {
        mActivityOptions = activityOptions;
    }

    public Bundle toBundle() {
        return mActivityOptions.toBundle();
    }

    public void update(ActivityOptionsCompatJB otherOptions) {
        mActivityOptions.update(otherOptions.mActivityOptions);
    }
}
複製代碼

 

我們可以完全瞭解到,4.x上能用的就這麼三個動畫效果,第一個第三我個人認爲沒啥用處,第二個效果好點,但僅僅適用於照片牆。於是就很悲劇了,這個新的類僅僅帶來了低版本兼容不報錯的效果,對於新的特性各種不支持。反過來想,反正動畫這個東西對用戶來說好看和不好看也沒差,功能是最主要的。

這個是講5.0動畫效果的文章,如果做5.0開發的話可以看看。但我估計在4.x主流的今天,這些特效還只能自己寫兼容包了。

http://blog.csdn.net/a396901990/article/details/40187203

 

動畫

好了,雖然我們不能用這麼酷炫的動畫,但我們還可以用傳統動畫嘛。我研究了下圖片放大的效果,寫了一篇文章,其實還可以繼續優化。貼上文章地址和效果圖。

地址:http://www.cnblogs.com/tianzhijiexian/p/4095756.html

效果圖:

 

下面分享下使用動畫的方法,在啓動activity的時候進行設置,然後在開啓的activity中的onBackPressed()也進行相應的設置,就能出現流暢的效果啦。

舉例:

MainActivity

複製代碼
    private void simpleStartActivity() {
        Intent intent = new Intent(this,DetailActivity.class);  
        startActivity(intent);
        //overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
        overridePendingTransition(R.anim.slide_bottom_in, android.R.anim.fade_out);
    }
複製代碼

 

DetailActivity

複製代碼
package com.kale.activityoptionstest;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class DetailActivity extends ActionBarActivity{

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

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
        overridePendingTransition(0, R.anim.slide_bottom_out);
    }
    
}
複製代碼

 

這樣就可以實現,第二個Activity從屏幕下方出現,按下返回鍵後會從屏幕下方離開了。

 

最後給出幾個常用的動畫效果

slide_bottom_in.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true">

    <translate
        android:duration="300"
        android:fromYDelta="100%p"
        android:toYDelta="0.0" />

</set>
複製代碼

 

slide_bottom_out.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true">

    <translate
        android:duration="300"
        android:fromYDelta="0.0"
        android:toYDelta="100%p" />

</set>
複製代碼

 

slide_left_in.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="300"
        android:fromXDelta="-100.0%p"
        android:toXDelta="0.0" />

</set>
複製代碼

 

slide_left_out.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="300"
        android:fromXDelta="0.0"
        android:toXDelta="-100.0%p" />

</set>
複製代碼

 

slide_right_in.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="300"
        android:fromXDelta="100.0%p"
        android:toXDelta="0.0" />

</set>
複製代碼

 

slide_right_out.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="300"
        android:fromXDelta="0.0"
        android:toXDelta="100.0%p" />

</set>
複製代碼

 

slide_top_in.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:startOffset="50">  

    <translate 
        android:fromYDelta="-100%p"
        android:toYDelta="0%p"
        android:duration="300"/>

    
</set> 
複製代碼

 

slide_top_out.xml

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:startOffset="50" >

    <translate
        android:duration="300"
        android:fromYDelta="0%p"
        android:toYDelta="-100%p" />

</set>
發佈了28 篇原創文章 · 獲贊 36 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章