自己动手(一)──可拖动排序的 ListView(3)

来源:互联网 发布:族脉家谱软件 编辑:程序博客网 时间:2024/05/29 18:02

前言

到目前为止,大体功能已经实现。但是性能严重低下,看log,发现不停在进行垃圾回收。没有使用viewholder模式,每日调整次序都会刷新都是原因。尝试了一下优化,失败了,下次再试。

改进

  • 在拖动过程中item view的移动增加动画
  • 增加ListView已经滑动到顶部或者底部的判断,无法滑动的时候不再滑动,防止抖动
  • 给变量、函数改名

效果图

这里写图片描述

相关源码

完整源码:github

1.item view调整次序时的动画效果

这里的动画是通过很直接的方式实现的。即,我先缓慢把需要调整顺序的item view移动到目标位置,然后刷新整个ListView。缓慢的移动通过ValueAnimator + setTranslationY实现。

    /**     * figure which item need move when empty position change from old to new     *     * @param oldEmptyPosition     * @param newEmptyPosition     */    private void initNeedMoveItems(int oldEmptyPosition, int newEmptyPosition) {        needMoveItems.clear();        if (newEmptyPosition > oldEmptyPosition) {            for (int i = oldEmptyPosition + 1; i <= newEmptyPosition; i++) {                addItemIfNotNull(i);            }        } else {            for (int i = newEmptyPosition; i < oldEmptyPosition; i++) {                addItemIfNotNull(i);            }        }    }    private void addItemIfNotNull(int i) {        View item = getChildAt(i - getFirstVisiblePosition());        if (item != null) {            needMoveItems.add(item);        }    }
        itemAnimator = newEmptyPosition > oldEmptyPosition ? ValueAnimator.ofFloat(0, -draggingItemHeight) : ValueAnimator.ofFloat(0, draggingItemHeight);//currPosition > srcPosition则向上移动itemView        itemAnimator.setDuration(duration);        itemAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator valueAnimator) {                for (View needMoveItem : needMoveItems) {                    needMoveItem.setTranslationY((Float) valueAnimator.getAnimatedValue());                }            }        });        itemAnimator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animator) {            }            @Override            public void onAnimationEnd(Animator animator) {                itemMovementEnd(oldEmptyPosition, newEmptyPosition, reset);            }            @Override            public void onAnimationCancel(Animator animator) {                itemMovementEnd(oldEmptyPosition, newEmptyPosition, reset);            }            @Override            public void onAnimationRepeat(Animator animator) {            }        });        itemAnimator.start();

2.判断ListView是否到达顶部或者底部,无法滑动的时候不再滑动,防止抖动

    private boolean reachTop() {        if (getFirstVisiblePosition() == 0 && getChildAt(0).getTop() >= 0) {            return true;        }        return false;    }    private boolean reachBottom() {        if (getLastVisiblePosition() == getAdapter().getCount() - 1 && getChildAt(getChildCount() - 1).getBottom() <= getHeight()) {            return true;        }        return false;    }
    private boolean scrollListViewIfNeeded(float y) {        //the distance you want to scroll ListView        int dy = 0;        if (y < topBoundary && !reachTop()) {            dy = (int) ((topBoundary - y) / 10);        } else if (y > bottomBoundary && !reachBottom()) {            dy = (int) ((bottomBoundary - y) / 10);        }        if (dy == 0) {            //tell the event handler, i am not scrolling the ListView , you can move items if you want            return false;        } else {            //tell the event handler, i am scrolling the ListView , do not move items            setSelectionFromTop(getFirstVisiblePosition(), getChildAt(0).getTop()+dy);            return true;        }    }

TODO

  • 性能优化
  • 当手指停在ListView的顶部或底部且ListView可以滑动的时候,不停的滑动ListView
0 0