您的位置:首页 > 其它

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

2015-07-26 10:40 363 查看

前言

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

改进

在拖动过程中item view的移动增加动画

增加ListView已经滑动到顶部或者底部的判断,无法滑动的时候不再滑动,防止抖动

给变量、函数改名

效果图



相关源码

完整源码:github

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

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

[code]    /**
     * 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);
        }
    }


[code]        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是否到达顶部或者底部,无法滑动的时候不再滑动,防止抖动

[code]    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;
    }


[code]    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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: