2013-04-26 5 views
6

Ich habe versucht, einen 3D-Cube-Rotationseffekt beim Verschieben von einem Fragment zum anderen zu machen. Zuerst benutzte ich einen Übersetzungseffekt (auf XML), der mit FragmentTransaction.setCustomAnimations(...) aufruft und dann, wenn ich das Fragment öffne/schloß, spielte ich mit der Camera Klasse, um die Rotation zu machen.Android - Machen Sie Übersetzungen und objectAnimator auf der gleichen XML-Datei

Das funktionierte FEIN, aber scheint, dass ich ZU HABEN (fragen Sie mich nicht, warum) alle diese Animation mit nur XML-Datei verwenden. Nach einer langen Suche fand ich heraus, dass ich objectAnimator benutzen sollte, um die Rotation zu machen.

Verfolgt das Google-Beispiel und ich schaffe es, die Flip-Animation zu machen. Jetzt muss ich die Fragmente übersetzen, damit sie hineingleiten und herausrutschen. Scheint, dass ich objectAnimator nicht verwenden kann und den Effekt auf dieselbe XML-Datei übersetze. Da dieser Fehler angezeigt:

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

Alle Ideen, wie ich die Gleitwirkung machen und die objectAnimator auf der gleichen Zeit verwenden?

Vielen Dank für Ihre Zeit!

-Code i habe mit:

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> 

Fragment ein weiteres Fragment Aufruf:

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(); 
} 
(Würfel Rotation sollte zwischen diesen 2 sichtbar sein)

UPDATE:

Ich habe verwalten das vorherige Problem mit einer Klasse zu lösen, die meine framelayout des Fragments erstreckt ich verwende

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); 
    } 
} 

und dies die objectAnimator Hinzufügen :

<!-- 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" /> 

Dies funktioniert besser, aber die rottation Achsen in der Mitte des FrameLayout sind und es ist nicht maki die Illusion eines Würfels ... Ist es möglich, die Rotationsachsen auf einen bestimmten Punkt zu setzen?

Antwort

4

Das Problem wurde gelöst, indem ich meine eigenen Methoden auf dem erweiterten FrameLayout erstellte. Hier ist der Code aus dem erweiterten 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); 
    } 

Und auf dem 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"/> 

In diesem Fall @integer/card_flip_time_full steht für die Dauer der gesamten Animation und @integer/card_flip_rotation_off steht für den Grad (in diesem Fall -90%).

Danach, alles, was ich tun müssen, um diese Animation an der Arbeit machen wird, wenn das Fragment starten, um die XML-Dateien in der benutzerdefinierten Animation gesetzt

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

Hoffnung, dies zu jemandem nützlich sein kann ^^

+0

In meinem Fall musste ich die zusätzlichen Methoden (getXFraction, setXFraction ...) auf der Root-Ansicht der Fragmente anstelle der FrameLayout haben, aber das Ergebnis ist das gleiche .. Danke – codeskraps

+0

@codeskraps können Sie zeigen, wie du es getan hast die zusätzlichen Methoden in der Stammansicht der Fragmente hinzugefügt? Ich möchte ein Fragment verschieben und verwende dafür ein erweitertes FrameLayout. Es funktioniert, aber es hat einige Probleme. Ich suche nach einem besseren Weg, dies zu tun. – crubio

-1

eine Alternative zu der Antwort akzeptiert, könnten Sie einen Animator Satz definieren, wie hier zu sehen:

<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?

Verwandte Themen