2013-04-26 57 views
6

我一直在嘗試在從一個片段滑動到另一個片段時製作3D立方體旋轉效果。 首先我使用了翻譯效果(在XML上),調用FragmentTransaction.setCustomAnimations(...),然後,當打開/關閉片段時,我正在使用Camera類進行旋轉。Android - 在同一個XML文件上製作翻譯和objectAnimator

這是行之有效的,但似乎我必須(不要問我爲什麼)使用所有這個動畫只使用XML文件。經過漫長的搜索後,我發現我應該使用objectAnimator來進行旋轉。

跟着谷歌樣本,我設法做翻轉動畫。現在我需要翻譯碎片,使它們滑入並滑出。似乎我不能使用objectAnimator並在同一個XML文件上轉換效果。由於此錯誤出現:

java.lang.RuntimeException: Unknown animator name: translate at (...) 

有關如何使滑動效果和同時使用objectAnimator的任何想法?

謝謝你的時間!

代碼,我一直在使用:

card_flip_right_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android" > 
    <!-- Before rotating, immediately set the alpha to 0. --> 
    <objectAnimator 
     android:duration="0" 
     android:propertyName="alpha" 
     android:valueFrom="1.0" 
     android:valueTo="0.0" /> 

    <!-- Rotate. --> 
    <objectAnimator 
     android:duration="@integer/card_flip_time_full" 
     android:interpolator="@android:interpolator/accelerate_decelerate" 
     android:propertyName="rotationY" 
     android:valueFrom="180" 
     android:valueTo="0" /> 

    <!-- Half-way through the rotation (see startOffset), set the alpha to 1. --> 
    <objectAnimator 
     android:duration="1" 
     android:propertyName="alpha" 
     android:startOffset="@integer/card_flip_time_half" 
     android:valueFrom="0.0" 
     android:valueTo="1.0" /> 

</set> 

片段調用另一個片段:(立方體轉動的應該是這2間可見)

private void launchArticle(int prev, int pos){ 
     ArticleFragment newFragment = new ArticleFragment(); 
     Bundle args = new Bundle(); 
     args.putString("pos", pos); 
     args.putInt("prev", prev); 
     newFragment.setArguments(args); 
     android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
     Fragment currFrag = (Fragment)getFragmentManager().findFragmentById(R.id.headlines_fragment); 
     if (currFrag != null) { 
       transaction.hide(currFrag); 
     } 
     transaction.setCustomAnimations(
       R.animator.card_flip_right_in, 
       R.animator.card_flip_right_out, 
       R.animator.card_flip_left_in, 
       R.animator.card_flip_left_out 
       ); 

     transaction.replace(R.id.fragment_container, newFragment, pos); 
     transaction.addToBackStack(null); 

     transaction.commit(); 
} 

更新:

我管理使用擴展我的片段的FrameLayout我使用

SlidingFrameLayout.java

public class SlidingFrameLayout extends FrameLayout 
{ 
    private static final String TAG = SlidingFrameLayout.class.getName(); 
    public SlidingFrameLayout(Context context) { 
     super(context); 
    } 

    public SlidingFrameLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public float getXFraction() 
    { 
     final int width = getWidth(); 
     if(width != 0) return getX()/getWidth(); 
     else return getX(); 
    } 

    public void setXFraction(float xFraction) { 
     final int width = getWidth(); 
     setX((width > 0) ? (xFraction * width) : -9999); 
    } 

    public float getYFraction() 
    { 
     final int height = getHeight(); 
     if(height != 0) return getY()/getHeight(); else return getY(); 
    } 

    public void setYFraction(float yFraction) { 
     final int height = getHeight(); 
     setY((height > 0) ? (yFraction * height) : -9999); 
    } 
} 

一個類來解決前面的問題,並通過添加這給objectAnimator :

<!-- Move --> 
    <objectAnimator 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:duration="@integer/card_flip_time_full" 
     android:interpolator="@android:anim/linear_interpolator" 
     android:propertyName="xFraction" 
     android:valueFrom="-1" 
     android:valueTo="0" /> 

這工作更好,但旋轉軸位於FrameLayout的中間,它不是maki在立方體的錯覺中......是否可以在某個點上設置旋轉軸?

回答

4

通過在擴展FrameLayout上創建我自己的方法解決了這個問題。下面是從擴展的FrameLayout代碼:

//Rotate from Left to Right turning visible 
    public float getRotateLeftRightIn(){ 
     return getRotationY(); 
    } 
    public void setRotateLeftRightIn(int rotateLeftRightIn){ 
     setPivotX(getWidth()); 
     setPivotY(getHeight()/2); 
     setRotationY(rotateLeftRightIn); 
    } 

而關於XML:

<!-- Rotate. --> 
<objectAnimator 
    android:duration="@integer/card_flip_time_full" 
    android:interpolator="@android:interpolator/accelerate_decelerate" 
    android:propertyName="rotateLeftRightIn" 
    android:valueFrom="@integer/card_flip_rotation_off" 
    android:valueTo="0" 
    android:valueType="intType"/> 

在這種情況下,@integer/card_flip_time_full代表整個動畫的持續時間和@integer/card_flip_rotation_off代表的程度(在這種情況下, -90%)。

在此之後,我需要做的,使這個動畫的工作,開始時的片段,在自定義動畫

transaction.setCustomAnimations(enter,exit,popEnter,popExit); 

希望這可以在一定一種有用的設置XML文件^^

+0

在我的情況下,我不得不在碎片的根視圖上使用額外的方法(getXFraction,setXFraction ...),而不是FrameLayout,但結果是一樣的。謝謝 – codeskraps 2014-07-07 14:49:18

+0

@codeskraps你能告訴我你是怎麼做到的在碎片的根視圖上添加額外的方法?我想滑動一個片段,然後使用擴展的FrameLayout來實現。它有效,但它有一些問題。我正在尋找更好的方法來做到這一點。 – crubio 2015-09-04 12:42:52

-1

公認的答案的選擇,你可以定義一個動畫集,在這裏看到:

<item android:state_pressed="true"> 
    <set> 
     <objectAnimator android:propertyName="translationZ" 
     android:duration="100" 
     android:valueTo="2" 
     android:valueType="floatType"/> 
     <!-- you could have other objectAnimator elements 
      here for "x" and "y", or other properties --> 
    </set> 
    </item> 

    <item android:state_enabled="true" 
    android:state_pressed="false" 
    android:state_focused="true"> 
    <set> 
     <objectAnimator android:propertyName="translationZ" 
     android:duration="100" 
     android:valueTo="2" 
     android:valueType="floatType"/> 
    </set> 
    </item> 

How to use StateListAnimator?