onTouch事件中抬手时让View自动归位

2023-05-13,,

在onTouch回调方法中处理滑效果中,抬手时让programListFragment自动归位。在实现过程中,为了使得自动归位过程可见,在while循环中添加Thread.sleep(10)来处理。在实际运行过程中,自动归位过程不可见,只见界面卡顿一会,然后直接归位。这并不符合预期效果。那么为什么会卡顿一会然后就直接归位呢

以下是实现该效果的代码片段。

case MotionEvent.ACTION_UP:
    // Logger.i(TAG, "event.getAction():"+MotionEvent.ACTION_UP);
    xUp = event.getX();
    xCurrent = xUp;
    programWidth = programListFragment.getView().getMeasuredWidth();
    int xAutoDist = (params.leftMargin < programWidth / 2) ? -2 : 2;
    while(true) {
        newLeftMargin = params.leftMargin + (int)xAutoDist;
        if(newLeftMargin < 0) {
            params.leftMargin = 0;
            break;
        } else if(newLeftMargin > channelWidth) {
            params.leftMargin = channelWidth;
            break;
        } else {
            params.leftMargin = newLeftMargin;
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        programListFragment.getView().setLayoutParams(params);
    }
    break;
}

经过调试并没有发现Thread.currentThread().sleep(10)和Thread.sleep(10)之间有什么区别。

以下是解决这个问题的思路和代码片段:

将Thread.sleep(10)放在新建的子线程中,在休眠结束之后再调用handler来更新leftMargin。

case MotionEvent.ACTION_UP:
    // Logger.i(TAG, "event.getAction():"+MotionEvent.ACTION_UP);
    xUp = event.getX();
    xCurrent = xUp;
    programWidth = programListFragment.getView().getMeasuredWidth();
    final int xAutoDist = (params.leftMargin < programWidth / 2) ? -2 : 2;
    new Thread(){
        public void run() {
            while(true) {
                newLeftMargin = params.leftMargin + (int)xAutoDist;
                if(newLeftMargin < 0) {
                    params.leftMargin = 0;
                    break;
                } else if(newLeftMargin > channelWidth) {
                    params.leftMargin = channelWidth;
                    break;
                } else {
                    params.leftMargin = newLeftMargin;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.sendEmptyMessage(0);
            }
        }
    }.start();
    break;
}

新建一个handler来更新LayoutParams

final Handler handler = new Handler(){
    @Override
    public void handleMessage(android.os.Message msg) {
        programListFragment.getView().setLayoutParams(params);
    }
};

自动归位效果基本达到,但是还不理想。这种实现还存在以下问题:

1. 当programListFragment明显在右侧,用力往左一滑时,此时不管抬手时是否已经明显在左侧,都应该以一定速度并且逐渐降速的过程自动滑行归位到左侧。

2. 自动归位过程是匀速的,不符合实际效果。归位过程应该是一个减速的过程。

3. 滑出边界效果可以再优化一下。滑出边界之后,再反弹回来。

《onTouch事件中抬手时让View自动归位.doc》

下载本文的Word格式文档,以方便收藏与打印。