【转载请注明出处】
笔者: DrkCore
优快云 原文: Android:如何给ScrollView添加滑块滚动条
说到滚动控件广大开发者朋友们首先想到的无非就是 ListView 和 ScrollView 两大控件,对于前者而言添加滑块无非是 XML 里面一句话的事情,但是对于后者来说就没那么容易了,至少笔者至今并没有找到简单的解决方案。
也罢,没有轮子的话就自己造一个。思路的话比较简单粗暴:使用 SeekBar 作为滑块绑定到 ScrollView 上。
垂直的 SeekBar
要给 ScrollView 添加滑块的话 SeekBar 必须是垂直的,这里笔者使用的是 GitHub 上的 android-verticalseekbar。
当然,如果你想要给 HorizontalScrollView 添加滑块的话原生的SeekBar就够了。
ScrollView 的监听和滚动范围
大部分的控件都提供监听者模式的回调,然而不知道为什么 ScrollView 本身没有暴露监听滚动的方法。写个子类开发接口也是可以的,不过笔者这里是直接使用了 Google 官方提供的 NestScrollView。
我们先分析一下其回调接口:
public interface OnScrollChangeListener {
void onScrollChange(NestedScrollView v, int scrollX, int scrollY,int oldScrollX, int oldScrollY);
}
其中 scrollY 是当前的滚动位置,和可滚动范围的关系图解如下:
理解了这一层关系之后要做的就很简单了,我们将可滚动范围和 scrollY 映射到 SeekBar 上即可。
滚动绑定
明白了逻辑之后我们只需要将 ScrollView 的滚动映射到 SeekBar,再将 SeekBar 的用户拖动映射回 ScrollView 就行了。以下是笔者封装了的一个辅助类,注释比较详尽:
public class ScrollBindHelper implements SeekBar.OnSeekBarChangeListener, NestedScrollView.OnScrollChangeListener {
private final SeekBar seekBar;
private final NestedScrollView scrollView;
private final View scrollContent;
// 使用静态方法绑定并返回对象
public static ScrollBindHelper bind (SeekBar seekBar, NestedScrollView scrollView) {
ScrollBindHelper helper = new ScrollBindHelper(seekBar, scrollView);
seekBar.setOnSeekBarChangeListener(helper);
scrollView.setOnScrollChangeListener(helper);
return helper;
}
private ScrollBindHelper (SeekBar seekBar, NestedScrollView scrollView) {
this.seekBar = seekBar;
this.scrollView = scrollView;
this.scrollContent = scrollView.getChildAt(0);
}
// 用户是否正在拖动 SeekBar 的标志
private boolean isUserSeeking;
// 获取滚动范围
private int getScrollRange () {
return scrollContent.getHeight() - scrollView.getHeight();
}
@Override
public void onScrollChange (NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// 用户拖动 SeekBar 时不触发 ScrollView 的回调
if (isUserSeeking)</