zoukankan      html  css  js  c++  java
  • 在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);


    问题完美解决

     
    天生我才必有用,千金散去还复来!
  • 相关阅读:
    【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法
    【hibernate/JPA】对实体类的的多个字段建立唯一索引,达到复合主键的效果【spring boot】注解创建唯一索引和普通索引
    Java 的BigDecimal
    java BigDecimal实现精确加减乘除运算
    java 多线程处理一个list的集合
    Java之——redis并发读写锁,使用Redisson实现分布式锁
    用CountDownLatch提升请求处理速度
    使用 CountDownLatch 控制多个线程执行顺序
    JAVA正确的四舍五入方法
    SpringBoot集成redisson分布式锁
  • 原文地址:https://www.cnblogs.com/Jack-Lu/p/3449214.html
Copyright © 2011-2022 走看看