我正在尝试创建一个自定义的垂直SeekBar
,它将用于滚动ScrollView
中的文本。这是SeekBar
:
class CustomSeekBar : SeekBar {
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(h, w, oldh, oldw)
}
@Synchronized
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec)
setMeasuredDimension(measuredHeight, measuredWidth)
}
override fun onDraw(c: Canvas) {
c.rotate(90f)
c.translate(0f, -width.toFloat())
super.onDraw(c)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event)
if (!isEnabled) {
return false
}
when (event.action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> {
val i = (max - (max * event.y / height)).toInt()
progress = 100 - i
onSizeChanged(width, height, 0, 0)
}
MotionEvent.ACTION_CANCEL -> {
}
}
return true
}
}
这是我的代码,试图将ScrollView
附加到我的片段SeekBar
中的onStart
:
override fun onStart() {
super.onStart()
val helpScrollView = view!!.findViewById<ScrollView>(R.id.helpScrollView)
val helpSeekBar = view!!.findViewById<CustomSeekBar>(R.id.helpSeekBar)
helpScrollView.viewTreeObserver.addOnGlobalLayoutListener {
val scroll: Int = getScrollRange(helpScrollView)
helpSeekBar.max = scroll
}
val seekBarListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
val min = 0
if(progress < min) {
seekBar?.progress = min;}
helpScrollView.scrollTo(0, progress)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
}
helpSeekBar.setOnSeekBarChangeListener(seekBarListener)
}
private fun getScrollRange(scrollView: ScrollView): Int {
var scrollRange = 0
if (scrollView.childCount > 0) {
val child = scrollView.getChildAt(0)
scrollRange =
Math.max(0, child.height - (scrollView.height - scrollView.paddingBottom - scrollView.paddingTop))
}
return scrollRange
}
SeekBar
似乎仅对下半部分的触摸有反应,并且拇指阴影仍在屏幕上水平滚动。 ScrollView
稍微移动,但仅在滚动开始时沿一个方向移动。我在做什么错了?
答案 0 :(得分:1)
我们是谁来判断您需要做什么,客户几乎总是对的!
无论如何,如果您仍然想这样做,(可能会或可能不会),以下是我认为体系结构应尝试的外观:
如果您的文本真的很长,我敢打赌,如果将文本分成几行并使用recyclerview进行显示,您将获得更好的性能,这将使滚动“稍微容易一些”,因为您可以移动自己的recyclerview到一个位置(行!)。
好吧,出于好奇,我尝试了这个。我启动了AS,创建了一个带有“空活动”的新项目,并添加了一个内部带有TextView的ScrollView和一个位于底部(水平)的SeekBar。
以下是所有要点的要点:
https://gist.github.com/Gryzor/5a68e4d247f4db1e0d1d77c40576af33
该解决方案的核心功能是开箱即用:
scrollView.scrollTo(0, progress)
,其中progress
由seekBar的onProgressChanged()
中的框架回调返回给您。
现在的关键是为搜索栏设置正确的“最大值”。
这是通过 dodging 在ScrollView中使用以下方法获得的:
(应归功于我的想法,我来自here)
private fun getScrollRange(scrollView: ScrollView): Int {
var scrollRange = 0
if (scrollView.childCount > 0) {
val child = scrollView.getChildAt(0)
scrollRange =
Math.max(0, child.height - (scrollView.height - scrollView.paddingBottom - scrollView.paddingTop))
}
return scrollRange
}
假设您正在等待seekBar进行测量/布局(因此为什么我必须在treeObserver中执行此操作),这可以正常工作。