项目开发中突然遇到这样一个需求:滑动条在进度0-3时不可滑动,其他区域正常滑动。显示要去重新自定义一个SeekBar需要花费时间项目上不允许,但可以从原生SeekBar着手限制。
要限制SeekBar的触摸范围,实际上为限制SeekBar的触摸事件,代码如下:
mSeekBar.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int width = mSeekBar.getWidth();
if (mTouchLimit > 0) {
if (isRtl()) {
float limitWidth = (width - width / mMax * mTouchLimit);
if (event.getX() > limitWidth) {
if (event.getAction() == MotionEvent.ACTION_UP) {
final long downTime = SystemClock.uptimeMillis();
MotionEvent motionEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP, limitWidth, event.getY(), 0);
mSeekBar.onTouchEvent(motionEvent);
}
return true;
}
} else {
float limitWidth = width / mMax * mTouchLimit;
if (event.getX() < limitWidth) {
if (event.getAction() == MotionEvent.ACTION_UP) {
final long downTime = SystemClock.uptimeMillis();
MotionEvent motionEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP, limitWidth, event.getY(), 0);
mSeekBar.onTouchEvent(motionEvent);
}
return true;
}
}
}
return false;
}
});
其中mTouchLimit为int类型参数,代表限制滑动范围的值,例如当mTouchLimit为3时,增SeekBar只能触摸到0-3区域不可触摸。mMax为SeekBar的最大值。代码中isRtl()的判断为处理阿拉伯语言时滑动条方向左右翻转,因此触摸坐标限制需要重新换算。
private boolean isRtl() {
return TextUtilsCompat.getLayoutDirectionFromLocale(getResources().getConfiguration().locale) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
在触摸事件释放时调用mSeekBar.onTouchEvent(motionEvent)模拟发送触摸事件是为了解决滑块Thumb没有恢复的问题。