Проверьте обновленный ответ внизу для решения
Кто мы, чтобы судить, что вам нужно делать, клиент почти всегда прав!
В любом случае, если вы все еще хотели это сделать (это может или не может работать), вот как я думаю, что архитектура должна выглядеть следующим образом:
- SeekBar глуп, не должен знать НИЧЕГО о том, что он делает. Вы даете ему минус (0?) И МАКС (n). Вы подписываетесь на его слушателя и получаете «прогресс» обновления. (ха, это самая легкая часть)
- ScrollView, содержащий текст, также очень неразумный, помимо его основ, ему можно сказать, чтобы прокрутить до позиции (это, вероятно, потребует некоторой работы, но я уверен, что это не сложно).
- Расчет значения MAX будет определять, насколько сложным будет шаг 2. Если вы используете каждый «шаг» в прокручиваемом контенте как «строку текста», то это нормально, но вам необходимо учитывать изменения макета и повторные измерения, которые могут изменить размер текста. Не должно быть "сумасшедшим", но имейте это в виду, иначе вы получите первый отчет об ошибке, как только пользователь повернет телефон:)
- Если текст динамический (может изменяться в реальном времени), ваша функция для шага 3 должна быть максимально эффективной, вам нужно, чтобы эти цифры были как можно скорее.
- Реагировать на изменения прогресса с панели поиска и иметь прокручиваемую прокрутку контента будет либо очень просто (вы нашли способ сделать это очень легко), либо сложно, если вы не можете заставить ScrollView вести себя так, как вам хочется.
Альтернативный подход
Если ваш текст действительно длинный, держу пари, у вас будет лучшая производительность, если вы разделите текст на строки и будете использовать его для просмотра, что сделает прокрутку «немного легче», как вы могли бы переместить свое представление переработчика в позицию (линия!).
UPDATE
Ладно, из любопытства я попробовал это. Я запустил AS, создал новый проект с «Пустым действием» и добавил ScrollView с TextView внутри и SeekBar внизу (горизонтальный).
Вот суть со всеми соответствующими битами:
https://gist.github.com/Gryzor/5a68e4d247f4db1e0d1d77c40576af33
В своей основе решение работает из коробки :
scrollView.scrollTo(0, progress)
, где progress
возвращается вам обратным вызовом фреймворка в seekBar's onProgressChanged()
.
Теперь ключ должен установить правильный «Макс» для панели поиска.
Это получается путем уклонения частного метода в ScrollView с этим:
(кредит, где нужно, я получил эту идею от здесь )
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).