Android studio scrollview опустить вниз

ScrollView и HorizontalScrollView

При большом количестве информации, которую нужно поместить на экране приходится использовать полосы прокрутки. В Android существуют специальные компоненты ScrollView и HorizontalScrollView, которые являются контейнерными элементами и наследуются от ViewGroup. Обратите внимание, что класс TextView использует свою собственную прокрутку и не нуждается в добавлении отдельных полос прокрутки. Но использование отдельных полос даже с TextView может улучшить вид вашего приложения и повышает удобство работы для пользователя.

На панели инструментов компоненты можно найти в разделе Containers.

В контейнеры ScrollView и HorizontalScrollView можно размещать только один дочерний элемент (обычно LinearLayout), который в свою очередь может быть контейнером для других элементов. Виджет ScrollView, несмотря на свое название, поддерживает только вертикальную прокрутку, поэтому для создания вертикальной и горизонтальной прокрутки необходимо использовать ScrollView в сочетании с HorizontalScrollView. Обычно ScrollView используют в качестве корневого элемента, а HorizontalScrollView в качестве дочернего. Можно и наоборот, пробуйте.

В в теле метода onCreate() создайте ссылку на элемент TextView, объявленный в XML-разметке, и запишите в него через метод setText() какой-нибуль длинный текст, который не поместится в видимые размеры экрана устройства:

Запустив проект, вы должны увидеть вертикальную и горизонтальную полосы прокрутки при попытке скролирования.

Если полосы прокрутки вас раздражают, то используйте атрибут android:scrollbars=»none», который скроет их.

По такому же принципу можете вложить ImageView, чтобы просматривать большие картинки:

Методы scrollBy() и scrollTo()

Вы можете программно прокручивать контент с помощью методов scrollBy() и scrollTo(). Например, можно организовать автоматическую прокрутку во время чтения. В нашем примере мы будем прокручивать контент с помощью трёх кнопок.

Сам код для методов:

Дополнительное чтение

Библиотека ParallaxScrollView с использованием эффекта параллакса. Вы прокручиваете длинный текст, а задний фон прокручивается чуть медленнее. Возможно, кому-то пригодится. Там же можно скачать готовое демо и просмотреть в действии.

Источник

Могу ли я прокручивать ScrollView программно в Android?

есть ли способ прокрутить ScrollView программно на определенную позицию?

Я создал динамический TableLayout который находится в ScrollView . Поэтому я хочу, чтобы это было конкретное действие (например, нажатие кнопки и т. д.) конкретная строка должна автоматически прокручиваться в верхнюю позицию.

16 ответов

ответ от Pragna не всегда работает, попробуйте следующее:

я хотел, чтобы scrollView прокручивался непосредственно после onCreateView () (не после, например, нажатия кнопки). Чтобы заставить его работать, мне нужно было использовать ViewTreeObserver:

но будьте осторожны, что это будет называться каждый раз, когда что-то получает layouted (e.g Если вы установили вид невидимый или аналогичный), поэтому не забудьте удалить этот прослушиватель, если он вам больше не нужен:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) на SDK Lvl

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) в SDK Lvl >= 16

использовать что-то вроде этого:

здесь много хороших ответов, но я хочу добавить только одну вещь. Иногда случается, что вы хотите прокрутить ScrollView до определенного вида макета, а не полный прокрутки вверх или вниз.

простой пример: в регистрационной форме, если пользователь нажимает кнопку «Регистрация», когда текст редактирования формы не заполнен, вы хотите прокрутить до этого конкретного текста редактирования, чтобы сообщить пользователю, что он должен заполнить это поле.

В этом случае, вы можете сделайте что-нибудь вроде этого:

или, если вы хотите гладкую прокрутку вместо мгновенной прокрутки:

очевидно, вы можете использовать любой тип представления вместо редактирования текста. Обратите внимание, что getBottom() возвращает координаты представления на основе его родительского макета, поэтому все виды, используемые внутри ScrollView, должны иметь только родительский (например, линейный макет).

Если у вас есть несколько родителей внутри ребенка ScrollView, единственное решение, которое я нашел вызвать requestChildFocus на родительский вид:

Читайте также:  Bundle in fragment android

но в этом случае вы не можете иметь гладкий свиток.

Я надеюсь, что этот ответ может помочь кому-то с такой же проблемой.

Источник

Custom View, скроллинг и жесты в Android на примере простого вьювера картинок

В статье описываются детали реализации простого вьювера картинок и показываются некоторые тонкости имплементации скроллинга и обработки жестов.

И так, начнем. Ми будем разрабатывать приложения для просмотра картинок. Готовое приложение выглядит так (хотя скриншоты, конечно, слабо передают функционал):

Установить приложение можно либо из Маркета, либо установив вручную отсюда. Исходный код доступен здесь.

Главным элементом нашего приложения является класс ImageViewer который мы и будем разрабатывать. Но нужно также отметить, что для выбора файла для просмотра я не стал изобретать велосипед и взял готовый «компонент» здесь.

Компонент представляет собой activity, который вызывается при старте из главного activity. После выбора файла, мы его загружаем и показываем на экране с помощью класса ImageViewer. Рассмотрим класс более подробно.

Класс является наследником класса View и переопределяет только один его метод onDraw. Также класс содержит конструктор и метод загрузки изображения:

Если мы загрузим картинку по размерам больше чем экран смартфона, то отобразится только часть ее и у нас не будет способа ее подвинуть или уменьшить.

Добавим теперь возможность скроллинга. Скроллинг по своей сути представляет собой жест, при котором пользователь дотрагивается пальцем к экрану, передвигает его не отрывая, и отпускает. Для того чтоб иметь возможность обрабатывать события связанные с тач-скрином, нужно переопределить метод onTouchEvent. Метод принимает один параметр типа MotionEvent и должен возвратить true в случае обработки события. Через этот метод можно реализовать поддержку любого жеста, включая скроллинг.
Для распознавания скроллинга нам нужно зафиксировать момент дотрагивания, перемещения и отпускания. К счастью нету необходимости делать это вручную так как в Android SDK есть класс делающий всю работу за нас. Таким образом для того чтоб распознать жест скроллинга, нужно добавить в наш класс поле типа GestureDetector которое инициализируется объектом реализующим интерфейс OnGestureListener (именно этот объект будет получать события скроллинга). Также нужно переопределить метод onTouchEvent в классе ImageViewer и передавать обработку событий из него в наш объект типа OnGestureListener. Измененный класс ImageViewer (без неизмененных методов) представлен ниже:

Как видно на самом деле ми наследуем MyGestureListener не от OnGestureListener, а от SimpleOnGestureListener. Последний класс просто реализует интерфейс OnGestureListener с помощью пустых методов. Этим мы избавляем себя от реализации всех методов, выбирая только те, что нужно.

Теперь если загрузить большую картинку, мы, по крайней мере, сможем скролить ее. Но: во первых мы можем проскроллить за рамки картинки, во вторых нету скроллбаров, которые бы подсказали нам где мы находимся и сколько еще осталось до краев.

Решим для начала вторую проблему. Поиск в Интернет приводит нас к тому, что нужно переопределить методы computeHorizontalScrollRange и computeVerticalScrollRange. Эти методы должны возвратить реальные размеры картинки (на самом деле есть еще методы которые имеют отношение к скроллбарам – это методы computeHorizontalScrollExtent, computeHorizontalScrollOffset и такая же пара для вертикального скроллбара. Если переопределить и их, то тогда возвращать можно более произвольные значения). Но этого оказывается недостаточно – скроллбары в первых нужно включить, во вторых проинициализировать. Включаются они методами setHorizontalScrollBarEnabled и setVerticalScrollBarEnabled, инициализируются методом initializeScrollbars. Но вот незадача – последний метод принимает немного непонятный параметр типа TypedArray. Этот параметр должен содержать в себе набор стандартных для View атрибутов. Список можно увидеть здесь в таблице «XML Attributes». Если бы мы создавали наш view из XML, Android runtime бы автоматически составил такой список. Но так как мы создаем класс программно, нужно также создать этот список программно. Для этого нужно создать файл attrs.xml в каталоге res\values с таким содержимым:

В файле просто перечислены все атрибуты, которые были указаны в таблице, упомянутой выше (кроме некоторых на которые указывает компилятор как на ошибку – видимо в документации список приведен самый последний). Измененный класс ImageViewer (кроме неизменных методов):

Читайте также:  Андроиды доклад 5 класс

Не хотелось бы на этом останавливаться, поэтому давайте добавим поддержку жеста «бросок» (fling). Этот жест есть просто дополнение к жесту скроллинга, но учитывается скорость перемещения пальца в последние моменты (перед отпусканием), и если она не нулевая, скроллинг продолжается с постепенным затуханием. Поддержка этого жеста уже заложена в GestureDetector – поэтому нам нужно всего лишь переопределить метод onFling в классе MyGestureListener. Отловив это событие нам нужно еще некоторое время изменять положение скроллинга. Конечно, это можно сделать «вручную» с помощью таймеров или еще как, но опять же в Android SDK уже есть класс, реализующий нужный функционал. Поэтому нужно добавить в класс ImageViewer еще одно поле типа Scroller, которое и будет заниматься «остаточным» скроллингом – для старта скроллинга нужно вызвать его метод fling. Также нужно показать скроллбары (они ведь прячутся когда не нужны) вызовом метода awakenScrollBars. И последнее что нужно сделать – это переопределить метод computeScroll, который должен непосредственно делать скроллинг с помощью метода scrollTo (класс Scroller сам не занимается скроллингом – он просто работает с координатами). Код измененного класса ImageViewer представлен ниже:

В завершения разговора о жесте fling надо сделать одну мелочь – при прикосновении пальцем во время скроллинга от броска, нужно остановить скроллинг. На этот раз мы это сделаем «вручную» в методе onTouchEvent. Измененный метод представлен ниже:

Уже можно любоваться достаточно интересной физикой, но можно увидеть некоторые «глюки» при скроллинге за пределы картинки. Это происходит из-за того, что fling работает только в пределах картинки, а скроллинг без броска работает везде. Т.е. мы сможем выйти за рамки картинки только если очень плавно скролить (чтоб не срабатывал fling). Исправить этот «косяк» можно путем введения ограничение на обработку в метод onFling и обрабатывать бросок только если он не выходит за границы картинки. Измененный метод представлен ниже:

Теперь мы опять можем беспрепятственно скролить за рамки картинки. Кажется, эту проблему мы уже вспоминали… У нее есть элегантное решение, лежащее в том, что при отпускании пальца (при завершении скроллинга за рамками картинки) нужно картинку плавно вернуть в «положенное» место. И опять мы это сделаем «вручную» в методе onTouchEvent:

Вот теперь с уверенностью можно сказать что со скроллингом мы разобрались. Можем переходить к последнему жесту который хотелось бы реализовать – это жест pinch zoom.

Со стороны жест выглядит как растягивание или сжатие чего-то воображаемого на экране смартфона двумя пальцами. Пошагово жест происходит так: нажатие одним пальцем, нажатие вторым пальцем, изменение положения одного или двух пальцев не отпуская, отпускание второго пальца. Для определения величины масштабирования нужно вычислить соотношение между расстояниями между пальцами в момент начала жеста и в момент окончания жеста. Расстояние между пальцами находится по формуле sqrt(pow(x2 – x1, 2) + pow(y2 – y1, 2)). Также нужно отметить некоторое положение скроллинга которое нужно сохранять – ведь если жестом увеличить картинку, то положение скроллинга изменится (из-за измененного размера картинки). Это положение – а точнее точка, положение которой нужно сохранить, в терминологии Android SDK называется фокальной точкой, и находиться она посередине между двумя пальцами.
Реализовать жест как всегда можно самому, но и это к счастью уже реализовано в Android SDK (правда, только начиная с версии 2.2). Поможет в этом класс ScaleGestureDetector, инстанс которого добавим в наш класс. ScaleGestureDetector инициализируется обьектом, поддерживающим интерфейс OnScaleGestureListener, поэтому создадим также внутренний класс MyScaleGestureListener, который реализует методы onScaleBegin, onScale и onScaleEnd. Не забываем передать управление ScaleGestureDetector из метода onTouchEvent. Ну и самое главное – нужно как-то использовать данные масштабирования: их нужно учитывать во всех местах, где раньше фигурировали ширина и высота картинки (т.е. фактически нужно умножить эти параметры на коэффициент масштабирования). Финальный код класса ImageViewer можно посмотреть в исходниках.
На этом все. Надеюсь статься окажется полезной.

Источник

Могу ли я прокручивать ScrollView программно в Android?

Есть ли способ прокрутить a ScrollView программно в определенную позицию?

Читайте также:  Java application to android app

Я создал динамический TableLayout , который помещается в ScrollView . Поэтому я хочу, чтобы при определенном действии (например, нажатии кнопки и т.д.) Конкретная строка должна автоматически прокручиваться в верхнюю позицию.

Возможно ли это?

ОТВЕТЫ

Ответ 1

Ответ 2

Ответ от Pragna не всегда работает, попробуйте это:

если вы хотите прокрутить, чтобы начать

Ответ 3

Мне нужно, чтобы scrollView прокручивался непосредственно после onCreateView() (не после нажатия кнопки). Чтобы заставить его работать, мне нужно было использовать ViewTreeObserver:

Но будьте осторожны, что это будет вызываться каждый раз, когда что-то получится макетированным (например, если вы установите невидимый или похожий вид), не забудьте удалить этот прослушиватель, если он вам больше не нужен:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) на SDK Lvl public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) в SDK Lvl >= 16

Ответ 4

Используйте что-то вроде этого:

Ответ 5

Здесь есть много хороших ответов, но я хочу только добавить одну вещь. Иногда бывает, что вы хотите прокрутить свой ScrollView до определенного вида макета, а не полный свиток вверх или снизу.

Простой пример: в регистрационной форме, если пользователь нажимает кнопку «Регистрация», когда текст редактирования формы не заполняется, вы хотите прокрутить этот текст редактирования, чтобы сообщить пользователю, что он должен заполнить эту поле.

В этом случае вы можете сделать что-то вроде этого:

или, если вы хотите гладкую прокрутку вместо мгновенного прокрутки:

Очевидно, вы можете использовать любой тип представления вместо редактирования текста. Обратите внимание, что getBottom() возвращает координаты представления на основе его родительского макета, поэтому все представления, используемые внутри ScrollView, должны иметь только родительский элемент (например, Linear Layout).

Если у вас есть несколько родителей внутри дочернего элемента ScrollView, единственным найденным решением является вызов requestChildFocus в родительском представлении:

но в этом случае вы не можете иметь гладкую прокрутку.

Я надеюсь, что этот ответ может помочь кому-то с той же проблемой.

Ответ 6

Попробуйте использовать scrollTo метод Подробнее

Ответ 7

Если вы хотите прокручивать мгновенно, вы можете использовать:

Или если вы хотите прокручивать плавно и медленно, чтобы вы могли использовать это:

Ответ 8

У меня это получилось, чтобы прокрутить до конца ScrollView (с TextView внутри):

(я положил это на метод, который обновляет TextView)

Ответ 9

Скажем, вы получили один Layout и внутри этого, вы получили много Views . Итак, если вы хотите прокручивать до любого View программно, вам нужно написать следующий фрагмент кода:

content_main.xml

MainActivity.java

Если вы хотите прокрутить до определенного View , скажем txtview, в этом случае просто напишите:

И вы сделали..

Ответ 10

Примечание: если вы уже в потоке, вам нужно создать новый поток сообщений, или он не прокручивает новую длинную высоту до полного конца (для меня). Для примера:

Ответ 11

Добавление другого ответа, не связанного с координатами.

Это приведет к желаемому фокусу (но не к верхней позиции):

public void RequestChildFocus (просмотр дочернего объекта, просмотр сфокусирован)

дочерний — ребенок этого ViewParent, который хочет сосредоточиться. Это представление будет содержать сфокусированное представление. Это не обязательно то, что на самом деле имеет фокус.

сфокусировано — представление, которое является потомком ребенка, на самом деле имеющим фокус

Ответ 12

** для прокрутки до нужной высоты. Я придумал хорошее решение **

Ответ 13

просто прокрутка страницы:

Ответ 14

Каждый отправляет такие сложные ответы.

Я нашел простой ответ для прокрутки донизу, красиво:

И, если необходимо, вы можете поместить вторую строку кода выше в runnable:

Мне потребовалось много исследований и игр, чтобы найти это простое решение. Надеюсь, это тоже поможет!:)

Ответ 15

Я использовал Runnable с sv.fullScroll(View.FOCUS_DOWN); Он отлично работает для непосредственной проблемы, но этот метод заставляет ScrollView отображать Focus со всего экрана, если вы делаете AutoScroll каждый раз, никакая EditText не сможет получать информацию от пользователя, в моем решении использовался другой код под runnable:

sv.scrollTo(0, sv.getBottom() + sv.getScrollY());

делая то же самое, не теряя внимания к важным представлениям

Источник

Оцените статью