2013-04-26 4 views
6

Я пытался создать эффект вращения 3D-куба, перемещаясь от одного фрагмента к другому. Сначала я использовал переводный эффект (по XML) с FragmentTransaction.setCustomAnimations(...), а затем, открыв/закрыв фрагмент, я играл с разделом камеры, чтобы сделать поворот.Android - Выполнение переводов и objectAnimator в том же файле XML

Это работало FINE, но похоже, что у меня есть (не спрашивайте меня почему) использовать всю эту анимацию, используя только XML-файл. После долгого поиска я узнал, что я должен использовать objectAnimator для вращения.

Последовал образец Google, и мне удалось создать флип-анимацию. Теперь мне нужно перевести фрагменты, заставляя их скользить и выдвигаться. Кажется, я не могу использовать 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" /> 

Это работает лучше, но оси rottation находятся в середине FrameLayout, и это не создавая иллюзию куба ... Можно ли установить оси вращения на определенную точку?

ответ

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%).

После этого, все, что мне нужно сделать, чтобы сделать эту анимацию для работы, при запуске фрагмента, установите файлы XML в пользовательской анимации

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

Надежда это может быть полезно в какой-то один ^^

+0

В моем случае я должен был использовать дополнительные методы (getXFraction, setXFraction ...) в корневом представлении фрагментов вместо FrameLayout, но результат тот же. Спасибо – codeskraps

+0

@codeskraps вы могли бы показать, как вы добавили дополнительные методы в корневой вид фрагментов? Я хочу скопировать фрагмент, и я использую расширенный FrameLayout, чтобы сделать это. Он работает, но у него есть некоторые проблемы. Я ищу лучший способ сделать это. – crubio

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

Смежные вопросы