安卓使用Seekbar控制ScroolView的滑动距离,并让thumb显示在进度条的外层

在安卓开发中,我们很少用用到Seekbar这个控件,这个控件继承自PrograssBar.我们可以发现Seekbar和PrograssBar最大的区别就是进度条是否可以被拖动。
在这里插入图片描述
但是这里有个问题就是拖动条我们发现正常的设置之后会显示在进度条的里面,我们也找不到相关的Seekbar的Api去让拖动条显示在进度条的外层。
那么我们要怎么做来解决Seekbar的进度条显示在外层呢?下面是解决方法:

<android.support.v7.widget.AppCompatSeekBar
               android:id="@+id/seek_bar_class_system"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_22"
                android:minHeight="@dimen/dp_9"
                android:maxHeight="@dimen/dp_9"
                android:layout_centerInParent="true"
                android:progressDrawable="@drawable/bg_solid_dcdcdc_r10"
                android:thumbTintMode="screen"
                android:thumbOffset="@dimen/dp_18"
                android:layout_marginLeft="@dimen/dp_10"
                android:layout_marginRight="@dimen/dp_10"
                android:thumb="@drawable/bg_seekbar_thumb"
                style="?android:attr/progressBarStyleHorizontal" />

首先我们要把Seekbar当成PrograssBar一样的设置它的进度条成水平方向的,然后我们这里注意一下进度条的高度,如果进度条的高度设置的不够高,就会导致Seekbar的Thumb显示在进度条的里面,然后我们再找什么属性也无法让Thumb显示完整,也没有相关的Api。之前开发的时候遇到过,然后解决了问题之后,再过了两年又忘记了。
其实这也就是Seekbar比较坑的地方:

                 android:thumbTintMode="src_in"
                android:thumbOffset="@dimen/dp_18"

这两个属性看着像是提供给我们设置Seekbar的thumb的显示方式的,但是试过之后并没有什么用。这就是给了我们生的希望,看到的却是深渊。
其实android:thumbTintMode="multiply"属性,混合模式,用于滑块着色。 那么我们就可以理解一下几点了:

   1)Seekbar的Thumb显示不全的问题是因为,Seekbar设置的高度小于Thumb.
     2)Seekbar的高度设置成Seekbar的Thumb高度之后,Seekbar的高度又显示成了Thumb的高度,一般是显示过大了。
     3)我们设置maxHeight成Seekbar的高度的时候,控件的高度设置成Thumb的高度不会影响Thumb的实现高度。也就是说maxHeight是设置的是Seekbar的高度。

所以问题可以通过设置maxHeight的高度来约束实际的Seekbar的高度,然后设置控件的高度成Seekbar的Thumb的高度就可以了。
现在又一个新的需求,就是让Seekbar拖动的进度来控制ScrollView的滑动距离。我们可以理解一下大概的实现思路:

  1)监听Seekbar的拖动事件,根据拖动的进度值来控制ScrollView的实际滑动的距离。
  2)拖动的进度值要和滑动的距离关联起来,就需要知道这个关联系数,这个关联系数比较重要,设置的不对就会影响整体的效果。
  3)滑动ScrollView也需要改变Seekbar的进度,这样才不会显的不和谐成bug.

下面就是实现代码:

  val picturesScrollView = findView<MineVipMemberScrollView>(R.id.scl_class_system_pictures)
        val scrollSeekBar = findView<SeekBar>(R.id.seek_bar_class_system)

        var isTrackSeekBar = false;  //是否在拖动进度条
        picturesScrollView.setOnScrollChangeListener(object : View.OnScrollChangeListener{
            override fun onScrollChange(v: View?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int) {
                if(!isTrackSeekBar) {
                    scrollSeekBar.progress = (scrollX / picturesScrollView.maxScrollAmount) * 100
                }
            }
        })
        scrollSeekBar.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener{
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                val scrollMaxWidth = picturesScrollView.measuredWidth //获取可滑动的横向距离
                val pWidth = scrollMaxWidth / 100
                picturesScrollView.scrollTo(pWidth*progress,0)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                isTrackSeekBar = true
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                isTrackSeekBar = false
            }
        })

我们要实现联动,就是要设置它们之间的关联系数,这个系数我们在进度条中是获取的实际的ScrollView的宽度,这里也可以改成高度。然后让它除以100就是拖动进度和ScrollView之间的关系系数。在ScollView里面的拖动事件中,我们获取的拖动进度和最大的拖动进度之间的比值再乘以100就是拖动进度的值。
这里需要优化的是在ScrollView里面拖动,进度条显示的进度只有0和100,中间的进度没有办法显示,又优化方案的同学可以给我留言哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值