仿抖音seekBar 精准拖动 不跳跃

638 阅读2分钟

在Android开发中,SeekBar是一个常用的用户界面组件,它允许用户通过滑动来选择一个范围内的值。然而,标准的SeekBar实现方式可能无法满足所有需求。有时,我们希望实现一个特殊的SeekBar,它只能通过滑动事件来模拟拖动效果,传统的方式进度条会跳动。本文将介绍如何实现这种自定义SeekBar,以满足类似抖音的拖动效果的交互需求。

首先,我们需要了解这个特殊SeekBar的需求和特性。这个SeekBar需要能够通过触摸事件来模拟拖动效果,而不是传统的点击跳转进度的方式。用户只能拖动到已显示的进度,不能拖动到未显示的进度。当用户在SeekBar上移动手指时,我们需要模拟拖动效果,并更新SeekBar的进度。此外,当进度发生变化时,我们需要监听这个变化,并实现相应的显示效果。当用户停止拖动时,我们需要处理一些细节判断。

为了实现这个自定义SeekBar,我们需要进行以下步骤:

  1. 在布局文件中添加SeekBar元素,并设置其ID以便在代码中引用。
  2. 在Activity或Fragment中,通过ID找到这个SeekBar对象。
  3. 设置SeekBar的触摸监听器,以模拟拖动效果。在触摸事件中,使用setProgress方法来更新SeekBar的进度。
  4. 实现onProgressChanged方法来监听进度变化。在这个方法中,你可以根据进度变化来更新UI或执行其他操作。
  5. 实现onStopTrackingTouch方法来处理用户停止拖动时的逻辑。在这个方法中,可以进行一些细节判断和处理。 关键代码如下
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isTouchIng = true;
            performClick();
            downX = event.getX();
            downY = event.getY();
            Log.d("MotionEvent==", "downX=" + downX);
            mLastTouchDownTime = System.currentTimeMillis();
            break;
        case MotionEvent.ACTION_MOVE:
            moveX = event.getX();
            if (moveX - downX > 0) {
                lastProgress += Math.abs(moveX - downX);
            } else {
                lastProgress -= Math.abs(moveX - downX);
            }
            if (lastProgress > mCanSeekbar.getMax()) {
                lastProgress = mCanSeekbar.getMax();
            }
            if (lastProgress < 0) {
                lastProgress = 0;
            }
            //为了响应外层的recyclerview上下滑动
            if (Math.abs(event.getX() - downX) > Math.abs(event.getY() - downY)) {
                requestDisallowInterceptTouchEvent(true);
                mCanSeekbar.setProgress((int) lastProgress);
                Log.d("MotionEvent==", moveX + "moveX" + "===pro==" + lastProgress);
            } else {
                if (isTouchIng) {
                    downX = event.getX();
                    downY = event.getY();
                    return true;
                } else {
                    requestDisallowInterceptTouchEvent(false);
                }
            }
            downX = event.getX();
            downY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            //up中单击事件分出来给播放器
            if (isOnClickEvent() && mOnUserSeekListener != null) {
                mOnUserSeekListener.onClick();
            }
        case MotionEvent.ACTION_CANCEL:
            isTouchIng = false;
            canSeekBarChangeListener.onStopTrackingTouch(mCanSeekbar);
            break;
    }
    return true;
}

这种实现方式与网上常见的实现不同,后者通常禁用点击事件,只允许用户拖动头部的小块区域。我们的实现方式更加灵活,允许用户在整个SeekBar上拖动,而不仅仅是头部的小块区域。

下载地址: [(download.csdn.net/download/du…)]