在Android中动画移动一个View的位置,采用Scroller类实现Android动画之 View移动

在Android中动画移动一个View的位置,采用Scroller类实现

今天说最近自己遇到的一个问题,就是要用动画效果来移动一个VIew的位置。

这个具体的情况是,需要做一个SlidingMenu的app,之前找了一个开源的,但不知道为什么,用起来app的运行效率很低,会有卡顿的现象。无奈只要自己写了。

SlidingMenu核心的就是可以滑动拉开左侧和右侧的菜单。刚开始考虑用TranslationAnimation来做。不过TranslationAnimation并不是真的移动一个View的坐标,在网上找了找,需要在Animation结束的时候,重新去layout下View的坐标,经过测试,这个方式可以达到预期效果。代码如下:

final int xOffset = leftFrameLayout.getWidth();

        TranslateAnimation translateAnimation = new TranslateAnimation(0, xOffset, 0, 0);



        translateAnimation.setDuration(200);

        translateAnimation.setAnimationListener(new Animation.AnimationListener() {

            @Override

            public void onAnimationStart(Animation animation) {

                //To change body of implemented methods use File | Settings | File Templates.

            }



            @Override

            public void onAnimationEnd(Animation animation) {

                int left = xOffset;

                int top = centerFrameLayout.getTop();

                int width = centerFrameLayout.getWidth();

                int height = centerFrameLayout.getHeight();

                centerFrameLayout.clearAnimation();

                centerFrameLayout.layout(left, top, left + width, top + height);



                leftFrameLayout.bringToFront();

            }



            @Override

            public void onAnimationRepeat(Animation animation) {

                //To change body of implemented methods use File | Settings | File Templates.

            }

        });

        centerFrameLayout.startAnimation(translateAnimation);

貌似没什么问题了,不过我的界面中,当显示SldingMenu的侧边栏的时候,里面有个输入框,点击输入框弹出键盘的时候,会导致界面重新layout,这时候中间被移动的view,就又给自动移动回来了,看来用

centerFrameLayout.layout

无法解决键盘弹出时候的重绘。

这时考虑到使用Scroller类来进行动画移动。也是参考了网上的例子,将我中间部分的FrameLayout搞成一个自定义类,代码如下:

public class ScrollableFrameLayout extends FrameLayout {

    private Scroller scroller;



    public ScrollableFrameLayout(Context context) {

        super(context);

        init();

    }



    public ScrollableFrameLayout(Context context, AttributeSet attrs) {

        super(context, attrs);

        init();

    }



    public ScrollableFrameLayout(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

        init();

    }



    private void init(){

        scroller = new Scroller(getContext());

    }



    @Override

    public void scrollTo(int x, int y) {

        super.scrollTo(x, y);

        postInvalidate();

    }



    @Override

    public void computeScroll() {

        if (!scroller.isFinished()) {

            if (scroller.computeScrollOffset()) {

                int oldX = getScrollX();

                int oldY = getScrollY();

                int x = scroller.getCurrX();

                int y = scroller.getCurrY();

                if (oldX != x || oldY != y) {

                    scrollTo(x, y);

                }

                // Keep on drawing until the animation has finished.

                invalidate();

            } else {

                clearChildrenCache();

            }

        } else {

            clearChildrenCache();

        }

    }



   public void smoothScrollTo(int dx, int duration) {



        int oldScrollX = getScrollX();

        scroller.startScroll(oldScrollX, getScrollY(), dx, getScrollY(), duration);

        invalidate();

    }



    private void enableChildrenCache() {

        final int count = getChildCount();

        for (int i = 0; i < count; i++) {

            final View layout = (View) getChildAt(i);

            layout.setDrawingCacheEnabled(true);

        }

    }



    private void clearChildrenCache() {

        final int count = getChildCount();

        for (int i = 0; i < count; i++) {

            final View layout = (View) getChildAt(i);

            layout.setDrawingCacheEnabled(false);

        }

    }



}

然后在需要移动这个类的地方调用:

int xOffset = rightFrameLayout.getWidth();



        centerFrameLayout.bringToFront();



        centerFrameLayout.smoothScrollTo(-xOffset, SCROLL_DURATION);



        handler.postDelayed(new Runnable() {

            @Override

            public void run() {

                rightFrameLayout.setVisibility(View.INVISIBLE);

            }

        }, SCROLL_DURATION);


问题完美解决

 

你可能感兴趣的:(android)