如何顺利动画视图向上/向下基于使用ObjectAnimator拖累运动? [英] How to smoothly animate a view up/down based on a drag motion using ObjectAnimator?

查看:350
本文介绍了如何顺利动画视图向上/向下基于使用ObjectAnimator拖累运动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建的具有位于屏幕的顶部1/3 MapFragment并占据屏幕的底部2/3一个ListView的图。在ListView有一个处理的正上方,用户可以用它来拖动整个ListView的向上或向下的列表项。一旦用户发布他们的手指离开屏幕的ListView应该动画到壁橱顶部或底部边框整个屏幕。我有它至今工作,但动画并不顺利。有一个明显的暂停时,用户从屏幕释放其手指后,在ListView开始朝向最接近的边缘动画之前。我使用的是nineoldandroids实施ObjectAnimator,使得动画在pre-蜂窝设备的工作。有任何想法吗?

下面是我的onTouch implement执行如下:

 公共布尔onTouch(视图V,MotionEvent事件){
    最终的LayoutParams listLp =(的LayoutParams)mListFrame.getLayoutParams();
    最终诠释TOPMARGIN = -mHandleShadow.getHeight();
    最终诠释middleMargin = getResources()getDimensionPixelSize(R.dimen.map_handle_margin_top)。
    。最终诠释bottomMargin = getView()的getHeight() - mHandle.getHeight() - mHandleShadow.getHeight();    开关(event.getAction()){
        案例MotionEvent.ACTION_DOWN:
            mInitY =(int)的event.getRawY();
            mTopMargin = listLp.topMargin;            打破;
        案例MotionEvent.ACTION_MOVE:
            INT Y = mTopMargin +(INT)event.getRawY() - mInitY;            如果(γ&GT = -mHandleShadow.getHeight()及&放大器; Y&下; =(mViewHeight - mHandle.getHeight() - mHandleShadow.getHeight())){
                listLp.topMargin = Y;
                mListFrame.setLayoutParams(listLp);
            }            打破;
        案例MotionEvent.ACTION_UP:
            如果((mInitY> event.getRawY()及&放大器; mClosestAnchor == Anchor.MIDDLE)||(listLp.topMargin&所述; middleMargin&放大器;&放大器; mClosestAnchor == Anchor.BOTTOM)){
                ObjectAnimator动画= ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame),TOPMARGIN,TOPMARGIN);
                animator.setInterpolator(新AccelerateInterpolator());
                animator.start();                mClosestAnchor = Anchor.TOP;
            }
            如果其他人((mInitY< event.getRawY()及和放大器; mClosestAnchor == Anchor.MIDDLE)||(listLp.topMargin> middleMargin和放大器;&安培; mClosestAnchor == Anchor.TOP)){
                ObjectAnimator动画= ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame),TOPMARGIN,bottomMargin);
                animator.setInterpolator(新AccelerateInterpolator());
                animator.start();                mClosestAnchor = Anchor.BOTTOM;
            }
            其他{
                ObjectAnimator动画= ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame),TOPMARGIN,middleMargin);
                animator.setInterpolator(新AccelerateInterpolator());
                animator.start();                mClosestAnchor = Anchor.MIDDLE;
            }            打破;
    }    返回true;
}


解决方案

终于解决了该问题读谷歌的切特·哈泽的答案,在这里找到一个类似的问题了。 http://stackoverflow.com/a/14780019/476005

调整每一帧在视图上的保证金是过于昂贵,总是断断续续,除非你正在移动的视图非常简单。因此,要解决这个问题,我做了我的OnTouch(...)下面的方法:


  1. 在MotionEvent.ACTION_DOWN:设置视图的高度,它的最大高度

  2. 在MotionEvent.ACTION_MOVE:动画视图的Y属性设置为event.getRawY为0的持续时间

  3. 在MotionEvent.ACTION_UP:动画视图的Y属性视图的父母的优势之一。在这里做最重要的事情是设置视图适当地onAnimationEnd的高度。

我希望这有助于大家。

I created a view that has a MapFragment that occupies the top 1/3 of the screen and a ListView that occupies the bottom 2/3 of the screen. The ListView has a "handle" directly above its list items that the user can use to drag the entire ListView up or down. Once the user releases their finger off of the screen the ListView should animate to the closet top or bottom border of the entire screen. I have it working so far but the animation is not smooth. There is a noticeable pause, after the user release their finger from the screen, before the ListView starts animating towards the closest edge. I'm using the nineoldandroids implementation of ObjectAnimator so that the animations work on pre-Honeycomb devices. Any ideas?

Here's my onTouch impl below:

public boolean onTouch(View v, MotionEvent event) {
    final LayoutParams listLp = (LayoutParams) mListFrame.getLayoutParams();
    final int topMargin = -mHandleShadow.getHeight();
    final int middleMargin = getResources().getDimensionPixelSize(R.dimen.map_handle_margin_top);
    final int bottomMargin = getView().getHeight() - mHandle.getHeight() - mHandleShadow.getHeight();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mInitY = (int) event.getRawY();
            mTopMargin = listLp.topMargin;

            break;
        case MotionEvent.ACTION_MOVE:
            int y = mTopMargin + (int) event.getRawY() - mInitY;

            if (y >= -mHandleShadow.getHeight() && y <= (mViewHeight - mHandle.getHeight() - mHandleShadow.getHeight())) {
                listLp.topMargin = y;
                mListFrame.setLayoutParams(listLp);
            }

            break;
        case MotionEvent.ACTION_UP:
            if ((mInitY > event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin < middleMargin && mClosestAnchor == Anchor.BOTTOM)) {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", topMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.TOP;
            }
            else if ((mInitY < event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin > middleMargin && mClosestAnchor == Anchor.TOP)) {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", bottomMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.BOTTOM;
            }
            else {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", middleMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.MIDDLE;
            }

            break;
    }

    return true;
}

解决方案

Finally fixed the issue after reading Google's Chet Haase's answer to a similar question found here. http://stackoverflow.com/a/14780019/476005

Adjusting a view's margin on every frame is too expensive and will always stutter unless the View you're moving is very simple. So to fix this, I do the following in my OnTouch(...) method:

  1. On MotionEvent.ACTION_DOWN: Set the View's height to it's maximum height.
  2. On MotionEvent.ACTION_MOVE: Animate the View's "y" property to the event.getRawY with a duration of 0.
  3. On MotionEvent.ACTION_UP: Animate the View's "y" property to one of the View's parent's edges. The important thing to do here is to set the height of the View appropriately in onAnimationEnd.

I hope this helps everyone.

这篇关于如何顺利动画视图向上/向下基于使用ObjectAnimator拖累运动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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