Android:使用 ObjectAnimator 使用 View 维度的分数转换 View [英] Android: Using ObjectAnimator to translate a View with fractional values of the View's dimension

查看:20
本文介绍了Android:使用 ObjectAnimator 使用 View 维度的分数转换 View的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看来,AnimationInflater 不再接受旧的视图动画(translatescale 等),至少从 ICS 开始.我在 4.0.4 中阅读了它的代码,它明确地只需要 XML 元素 setobjectAnimatoranimator.

It appears that the old view animations (translate, scale, and so on) are no longer accepted by the AnimationInflater, at least as of ICS. I read its code in 4.0.4, and it explicitly expects only the XML elements set, objectAnimator, animator.

即使 http://developer.android.com/guide/topics/上的文档resources/animation-resource.html 继续包含视图动画,它们似乎已被弃用.例如,尝试使用它们会导致错误 java.lang.RuntimeException: Unknown animator name: translate.

Even though the documentation at http://developer.android.com/guide/topics/resources/animation-resource.html continues to include the view animations, they appear to be deprecated. Trying to use them results in, for instance, the error java.lang.RuntimeException: Unknown animator name: translate.

因此,有必要使用 Android 的 ObjectAnimator.但是,它不接受其自身或其父级的相关维度的分数值(例如,translationX 的宽度),就像旧视图动画以 "75%p"<的形式所做的那样/代码>.

As such, it becomes necessary to use Android's ObjectAnimator. However, it does not accept fractional values of the associated dimension of itself or its parent (width for translationX, for example) as the old view animations did in the form "75%p".

在运行时手动构建 ObjectAnimator,通过以编程方式获取 Fragment 的大小,是不可行的,因为 FragmentTransaction 只接受由 resid 指定的声明性动画.

Constructing the ObjectAnimator manually at runtime, by programmatically fetching the size of the Fragment, isn't feasible because the FragmentTransaction only accepts declarative animations specified by a resid.

我的目标是在屏幕外翻译一个填满整个活动的片段(我基本上是在两个片段之间进行转换过渡).这是现有的 TranslationAnimation 实现(slide_in_right.xml,由于某种原因,它与其对应的 slide_out_left.xml 未在 中公开android.R.anim,因此我必须在我的代码库中复制它们):

My goal is to translate offscreen a Fragment that is filling up an entire Activity (I'm basically doing a shift transition between two fragments). This is the existing TranslationAnimation implementation (slide_in_right.xml, which along with its counterpart slide_out_left.xml is for some reason not exposed in android.R.anim, and I therefore have to duplicate them in my codebase):

<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
    android:fromXDelta="100%p"
    android:toXDelta="0"
    android:duration="@android:integer/config_mediumAnimTime"/>
</set>

我的 API 级别设置为 14.

My API level is set to 14.

谢谢!

推荐答案

实际上对象动画师接受小数值.但也许您不了解 objectAnimator 或更一般的值动画师的基本概念.值动画师将动画与属性相关的值(例如颜色、屏幕上的位置 (X,Y)、alpha 参数或任何你想要的).要创建这样的属性(在您的情况下为 xFraction 和 yFraction),您需要构建与此属性名称相关联的自己的 getter 和 setter.假设您想将 FrameLayout 从整个屏幕大小的 0% 转换为 25%.然后你需要构建一个自定义 View 来包装 FrameLayout 对象并编写你的 getter 和 setter.

Actually object animators accept fractional values. But maybe you didn't understand the underlying concept of an objectAnimator or more generally a value animator. A value animator will animate a value related to a property (such as a color, a position on screen (X,Y), an alpha parameter or whatever you want). To create such a property (in your case xFraction and yFraction) you need to build your own getters and setters associated to this property name. Lets say you want to translate a FrameLayout from 0% to 25% of the size of your whole screen. Then you need to build a custom View that wraps the FrameLayout objects and write your getters and setters.

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()
    {
        int width = getWindowManager().getDefaultDisplay().getWidth();
        return (width == 0) ? 0 : getX() / (float) width;
    }

    public void setXFraction(float xFraction) {
        int width = getWindowManager().getDefaultDisplay().getWidth();
        setX((width > 0) ? (xFraction * width) : 0);
    }
}

然后就可以用xml的方式来声明object animator,将xFraction放在property xml属性下,并用AnimatorInflater对其进行inflate

Then You can use the xml way to declare the object animator putting xFraction under the property xml attribute and inflate it with a AnimatorInflater

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator 
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="xFraction" 
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="0.25" 
android:duration="500"/>

或者你可以只使用java行代码

or you can just use the java line code

ObjectAnimator oa = ObjectAnimator.ofFloat(menuFragmentContainer, "xFraction", 0, 0.25f);

希望对你有帮助!

奥利维尔

这篇关于Android:使用 ObjectAnimator 使用 View 维度的分数转换 View的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆