【问题标题】:Can't get objectAnimator working with xFraction无法让 objectAnimator 与 xFraction 一起使用
【发布时间】:2014-10-31 04:36:56
【问题描述】:

我正在尝试在 Fragments 之间制作 slide-in/slide-out 动画。我知道 StackOverflow 上有大量类似的问题,但请相信我 - 我尝试了所有这些问题,但没有一个有效。

按照我的代码(基本上取自类似问题):

自定义布局

public class SlidingFrameLayout extends FrameLayout {

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

分片交易

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.animator.card_enter_right, R.animator.card_out_left);
ft.replace(R.id.quiz_container, CardFragment.newInstance());
ft.commit();

对象动画师

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:interpolator="@android:anim/linear_interpolator"
    android:propertyName="xFraction"
    android:valueFrom="1.0"
    android:valueTo="0.0"
    android:valueType="floatType" />

布局文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.my.package.views.SlidingFrameLayout
        android:id="@+id/quiz_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- Other views -->

</FrameLayout>

所以当我运行这段代码时,什么都没有发生。片段被替换,但没有动画
做错了什么?

注意:如果我使用"x" 而不是"xFraction" 运行动画并将值更改为假设from:1280 to:0 它正在工作。不幸的是,这对我来说不是一个解决方案,因为我需要一个“百分比值”,因为显示分辨率范围很广。


解决方案

感谢pskink 引导我找到解决方案。我一直以为我的Fragment的容器需要实现getXFraction()/setXFraction()方法。但事实并非如此。你的 Fragments 布局需要实现getXFraction()/setXFraction。 所以基本上我改变了我的片段布局,如下所示:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:prefix="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="40dp"
    prefix:cardCornerRadius="4dp">

<!-- Content -->
</android.support.v7.widget.CardView>

到:

<com.my.package.views.SlidingFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:prefix="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="40dp"
        prefix:cardCornerRadius="4dp">

<!-- Content -->
    </android.support.v7.widget.CardView>
</com.my.package.views.SlidingFrameLayout>

【问题讨论】:

  • setXFraction 和 getXFraction 应该在根视图中定义:从 onCreateView 返回的视图,通过移除根 FrameLayout 来测试它
  • 我也试过了,不幸的是问题仍然存在。我刚刚编辑了我的问题。
  • 在这种情况下,将 xml 文件中的 objectAnimator 替换为 animator,覆盖 Fragment.onCreateAnimator,加载您的 animator 并设置更新监听器
  • 我刚试过这个。尽管没有任何改变,但一切都被正确调用。老实说我不知道​​这样做的目的是什么?!
  • 你的监听器是否被调用?

标签: android android-fragments android-animation fragmenttransaction objectanimator


【解决方案1】:

由于上述代码清单只是部分代码,我想我会与您分享一个完整的工作示例。它的工作原理如问题中所述。

按下按钮在 2 个片段 A 和 B 之间切换(通过从右到左的滑动动画)。这些片段只是具有不同背景的愚蠢文本(AAAAAA 和 BBBBB)。

MainActivity.java

package com.example.slidetrans;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity {

    boolean showingA = true;
    Button button;

    A a;
    B b;

    private void incarnate(FragmentManager fm){
        int layoutId = R.id.frame;
        boolean fragmentWasNull = false;
        Fragment f = fm.findFragmentById(layoutId);
        if (f == null){
            if (showingA){
                f = a = new A();
            } else {
                f = b = new B();
            }
            fragmentWasNull = true;
        }
        if (fragmentWasNull){
            FragmentTransaction ft = fm.beginTransaction();
            ft.add(layoutId, showingA ? a : b,  "main").commit(); 
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        FragmentManager fm = getFragmentManager();
        incarnate(fm);
        button = (Button)findViewById(R.id.button);
        OnClickListener listener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getFragmentManager();
                FragmentTransaction transaction = fm.beginTransaction();
                transaction.setCustomAnimations(R.anim.in, R.anim.out);
                transaction.replace(R.id.frame, showingA ? new B() : new A()).commit();
                showingA = !showingA;
                button.setText(showingA ? "slide in B" : "slide in A");
            }
        };
        button.setOnClickListener(listener);
    }
}

LL.java

package com.example.slidetrans;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class LL extends LinearLayout {

    public LL(Context context) {
        super(context);
    }

    public LL(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();
        float newWidth = (width > 0) ? (xFraction * width) : -9999;
        setX(newWidth);
    }
}

main.xml(布局)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="slide in B" />

    <FrameLayout
        android:id="@+id/frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

    </FrameLayout>

</LinearLayout>

a.xml(布局)

<?xml version="1.0" encoding="utf-8"?>
<com.example.slidetrans.LL xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#00FF00"
>

    <TextView
        android:id="@+id/aText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="AAAAAAAAAAAAAAAAAA"
        android:textSize="30sp"
        android:textStyle="bold"
    />

</com.example.slidetrans.LL>

b.xml(布局)

<?xml version="1.0" encoding="utf-8"?>
<com.example.slidetrans.LL xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#FFFF00"
>

    <TextView
        android:id="@+id/bText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textStyle="bold"
        android:text="BBBBBBBBBB"
    />

</com.example.slidetrans.LL>

in.xml(动画)

<?xml version="1.0" encoding="utf-8"?>
<set  xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
    android:duration="500"
    android:interpolator="@android:anim/linear_interpolator"
    android:propertyName="xFraction"
    android:valueFrom="1.0"
    android:valueTo="0.0"
    android:valueType="floatType" />

</set>

out.xml(动画)

<?xml version="1.0" encoding="utf-8"?>
<set  xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
    android:duration="500"
    android:interpolator="@android:anim/linear_interpolator"
    android:propertyName="xFraction"
    android:valueFrom="0.0"
    android:valueTo="-1.0"
    android:valueType="floatType" />

</set>

【讨论】:

    【解决方案2】:

    setXFraction 和 getXFraction 应该在根视图中定义:您从 onCreateView 返回的视图,在您的情况下是自定义 CardView

    【讨论】:

      【解决方案3】:

      @mathheadinclouds 提供的示例对我有用,在该行中使用“R.animator.in”而不是 R.anim.in

      transaction.setCustomAnimations(R.anim.in, R.anim.out);
      

      【讨论】:

        猜你喜欢
        • 2018-01-02
        • 2016-11-14
        • 2015-02-01
        • 2019-05-10
        • 2017-11-20
        • 2011-05-24
        • 2019-05-17
        • 2018-06-02
        • 2019-04-30
        相关资源
        最近更新 更多