当前位置: 代码迷 >> Android >> 在Android中卡通片移动一个View的位置,采用Scroller类实现
  详细解决方案

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

热度:41   发布时间:2016-05-01 10:59:29.0
在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);

问题完美解决

  相关解决方案