• 在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);


    问题完美解决

     
    天生我才必有用,千金散去还复来!
  • 相关阅读:
    JavaScript 工作必知(九)function 说起 闭包问题
    AngularJs(七) 模块的创建
    javaScript 工作必知(八) 属性的特性 值、写、枚举、可配置
    javaScript 工作必知(七) 对象继承
    javaScript 工作必知(六) delete in instanceof
    数据可视化产品示例和相关文章
    echarts的世界地图json
    webstorm使用svn
    初识产品运维
    UglifyJS 压缩选项
  • 原文地址:https://www.cnblogs.com/Jack-Lu/p/3449214.html
Copyright © 2020-2023  润新知