如何在Android的ObjectAnimator中使用百分比值

29

我正在使用Android的objectAnimator将按钮从底部向上移动。现在我正在使用以下代码:

ObjectAnimator transAnimation = ObjectAnimator.ofFloat(button,"translationY",0,440);
        transAnimation.setDuration(440);
        transAnimation.start();

我也尝试了下面的示例代码。但问题仍然存在。

ObjectAnimator transAnimation = ObjectAnimator.ofFloat(loginLayout, "translationY",0f,0.8f);
                    transAnimation.setDuration(480);
                    transAnimation.start();
在大屏设备上运行良好,但在小屏设备上会偏离屏幕。我希望它始终保持在屏幕顶部,而不受不同屏幕大小的影响。我认为我必须以百分比(例如0%到100%或0到100%p)的形式给出值。因此,我的问题是如何在Android的objectAnimator中以百分比形式给出值。我还注意到,这个objectAnimator仅在HoneyComb中引入。所以是否有向后兼容的库可以在低版本中运行它?能否指导我找到解决方案。
我还尝试扩展View并在offset()中编写属性的getter和setter。但它仍然无法完全移动到屏幕顶部。这里是我使用的代码。
@SuppressLint("NewApi") public float getXFraction()
    {
        int width = context.getWindowManager().getDefaultDisplay().getHeight();
        return (width == 0) ? 0 : (getY());
    }

    @SuppressLint("NewApi") public void setXFraction(float xFraction) {
        int width = context.getWindowManager().getDefaultDisplay().getWidth();
        setY((width > 0) ? (width) : 0);
    }

提前致谢


1
对于那些正在寻找答案的人,这里是解决方法。 - azizbekian
5个回答

10

要在Honeycomb之前的设备上使用ObjectAnimator,请将NineOldAndroids库添加到您的项目中,并更改导入以使用com.nineoldandroids.animation.ObjectAnimator

要在ObjectAnimator中使用百分比值而不是getXFractionsetXFraction方法,您必须添加getYFractionsetYFraction方法,如下所示:

public float getYFraction() {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    int height = wm.getDefaultDisplay().getHeight();
    return (height == 0) ? 0 : getY() / (float) height;
}

public void setYFraction(float yFraction) {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    int height = wm.getDefaultDisplay().getHeight();
    setY((height > 0) ? (yFraction * height) : 0);
}

然后你可以创建一个名为project-folder/res/animator/move_bottom.xml的xml文件,内容如下

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

或者在代码中创建动画

final LoginLayout loginLayout = (LoginLayout) findViewById(R.id.login_layout);
final ObjectAnimator oa = ObjectAnimator.ofFloat(loginLayout, "yFraction", 0f, 0.8f);
oa.start();

确实,我尝试过这个方法...但是它仍然超出了屏幕范围。还有一件事是它突然跳到屏幕顶部,然后又回到底部。为什么会这样?在ObjectAnimator类中是否有类似于setFillAfter="true"的方法可以让它停留在终点而不返回原始位置? - Sanal Varghese
我认真地认为我在 ofFloat(target, propertyName, int, int) 方法中犯了一些错误。最后两个参数是 int,int。这些参数决定动画的起点和终点。但是该方法期望值以什么单位呈现...我的意思是它是否期望像素或 dp。当我找到设备屏幕高度并将该值传递给 ofFloat() 方法时,为什么它仍然超出了屏幕范围?请告诉我您的想法和建议。我做错了什么吗? - Sanal Varghese
ofFloat 方法中,最后两个或更多参数都是浮点数。请参阅官方文档此处链接 - vasart

4

如果你想使用ObjectAnimator从屏幕外创建动画,可以利用Android显示大小来实现。

    @Override
    public void onCreate(Bundle savedInstanceState) {

        ...

        sampleImage = BitmapFactory.decodeResource(getResources(), R.drawable.sample);

        myImage = (ImageView) findViewById(R.id.image_view);
        myImage.setImageBitmap(sampleImage);

        //In case API Level is 14 above.
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        float displayWidth = size.x;

        //In case API Level is 13 below.       
        //WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        //Display display = wm.getDefaultDisplay();
        //displayWidth = display.getWidth();

        animator = ObjectAnimator.ofFloat(myImage, "translationX", displayWidth,  0);
        animator.setDuration(500);

    }

抱歉,如果我的建议没有涵盖问题。


2
尝试使用ObjectAnimator的自定义属性,而不是创建具有自定义属性的自定义视图,您可以创建一个接受“fraction”参数的自定义属性:
Property<View, Float> property = new Property<View, Float>(Float.TYPE, "translation_x_fraction") {
        @Override public Float get(View view) { 
            return view.getWidth() <= 0 ? 0 : view.getTranslationX() / view.getWidth();
        }

        @Override public void set(View view, Float value) {
            view.setTranslationX(view.getWidth() * value);
        }
}

ObjectAnimator.ofFloat(view, property, 0f, 1f);

0

我已经用这种方式做过了,花费了太多时间,但它会节省你的时间。

参数:

  1. 视图(您支持的视图)
  2. 父宽度(您的视图的根)
  3. 子宽度(您想应用动画的对象或视图)
  4. %(您想移动对象或视图的百分比)

不要害怕参数,我在这里通过示例进行解释。

XMLJAVA代码:

activity_main.xml:

<LinearLayout
     android:id="@+id/llProgressParent"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_margin="5dp"
     android:layout_gravity="center"
     android:orientation="horizontal"
     android:weightSum="1" >

     <View
        android:id="@+id/viewSuppot"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0" >
     </View>

     <ImageView
        android:id="@+id/ivProgressChild"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

MainActivity.java:

private LinearLayout llProgressParent;
private View viewSuppot;
private ImageView ivProgressChild;
private int childWidth, parentWidth;
private int percentage = 75;

onCreate()方法中:

viewSuppot = findViewById(R.id.viewSuppot);

llProgressParent = (LinearLayout)findViewById(R.id.llProgressParent);
llProgressParent.post(new Runnable() {
      @Override
      public void run() {
          parentWidth = llProgressParent.getMeasuredWidth();
      }
  });


 ivProgressChild = (ImageView)findViewById(R.id.ivProgressChild);
 ivProgressChild.post(new Runnable() {
      @Override
      public void run() {
          childWidth = ivProgressChild.getMeasuredWidth();
      }
  });

方法:

private void animateViewByPercentageOrProgrss(final View view,  int parentWidth, int childWidth, int percentage){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ValueAnimator anim = ValueAnimator.ofInt(view.getMeasuredWidth(), (int) (((float) percentage * parentWidth) / 100)-(childWidth/2));
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.width = val;
                view.setLayoutParams(layoutParams);
            }
        });
        anim.setDuration(2000);
        anim.start();
    }

如何调用方法

animateViewByPercentageOrProgrss(viewSuppot, parentWidth, childWidth, percentage);

完成了


-1

这样怎么样?获取父布局的 Y 维度,将其除以 2,然后对其进行动画处理...

int a = parentlayout.getY();
view.animate().setTranslationY(a/2).start();

这个可以按照你想要的方式工作....

这是我的第一个回答,如果有问题请告诉我...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接