Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290

Узнать положение recyclerView

16.10.2024, 02:41. Показов 1683. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
AndroidStudio Java

Нужно узнать положение recyсlerView. Если он перемотан до конца вниз, то при добавлении новых элементов сдвигать его на последний элемент, если же он "отмотан" куда то то оставить как есть.
Событие onScrooled выдает значения в абсолютных единицах и непонятно каких (пикселях что ли). Как узнать какой элемент сейчас отображается на экране?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.10.2024, 02:41
Ответы с готовыми решениями:

[Kotlin] Как узнать и сравнить положение двух imageView?
Есть две картинки: клочок бумаги и корзина. Как сделать так, чтобы бумага исчезала, когда ее перетащат в корзину. С перетаскивание я...

Advanced RecyclerView и Expandable RecyclerView
Сделал expandable recycler view на основе advancedRecyclerView сборочки, но не важно это думаю, наследуется от обычного RecyclerView. ...

Узнать положение div
Здравствуйте,уважаемые,форумчанине. У меня такой вот вопрос,подскажите,пожалуйста,как такое реализовать есть div <div id...

10
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
16.10.2024, 10:48
Цитата Сообщение от Alex1126 Посмотреть сообщение
абсолютных единицах и непонятно каких (пикселях что ли)
В общем что вам надо.
есть такой метод findViewHolderForLayoutPosition() в него надо передать индекс последнего видимого View. Надеюсь с этим проблем не будет?
Далее вы получили ViewHolder, и уже от него ищите, последний это айтем в адаптере или нет.
0
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290
16.10.2024, 23:15  [ТС]
Так мне и нужно как раз узнать номер последнего видимого элемента.

Вообщем что мне надо:
В recyclerView периодически добавляются элементы, ну типа сообщения лога. Вот. И когда добавляется новое то надо список подвинуть что бы последнее отобразить. Это я сделал. Но если пользователь отмотал куда-нить список что бы посмотреть что то там что было ранее, то не надо при добавлении нового элемента крутить список вниз к нему. То есть мне надо узнать, находится ли список в нижнем положении или нет.
0
67 / 43 / 5
Регистрация: 24.08.2013
Сообщений: 678
17.10.2024, 07:33
Лучший ответ Сообщение было отмечено Alex1126 как решение

Решение

Попробуйте так:
Java
1
last_visible_pos = ((LinearLayoutManager) recycler_view.getLayoutManager()).findLastCompletelyVisibleItemPosition();
1
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
17.10.2024, 07:40
Slon747, Это к стати тоже вполне рабочий вариант.
0
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290
18.10.2024, 00:02  [ТС]
Сделал, заработало. Спасибо большое. Ну и пошел я развивать эту мысль. Решил еще сделать что бы при появлении клавиатуры сообщения "поднимались" и последнее оставалось последним. Но какая то чертовщина получается.

Вообщем загружаются у меня сообщения при создании формы. Список двигаю вниз. Будем считать это исходным положением.

Далее, ловим скролинг и запоминаем индекс последнего видимого элемента:
Java
1
2
3
4
5
6
7
8
9
10
        messagesRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                if (dy!=0) {
                    lastViewPositionRV=((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                    Log.v("myLogs","Запоминаем - "+lastViewPositionRV);
                }
                super.onScrolled(recyclerView, dx, dy);
            }
        });
Запомнили. Теперь ловим изменение окна (ну типа клава появилась)
Java
1
2
3
4
5
6
        messagesRv.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
            if ((bottom!=oldBottom) && (oldBottom>0)){
                Log.v("myLogs","Двигаем - "+ lastViewPositionRV);
                messagesRv.scrollToPosition(lastViewPositionRV);
            }
        });
Вроде все норм должно быть.
И запускаем. И вот тут начинается магия.
Вот лог при запуске примерно такой:
Java
1
2
3
4
23:57:34.772  V  Запоминаем - 25
23:57:34.792  V  Запоминаем - 26
23:57:34.804  V  Запоминаем - 26
23:57:34.821  V  Запоминаем - 27
Вот. Все. Список загрузился, последний элемент с номером 27.
Вызываем клавиатуру:
Java
1
23:59:03.273  V  Двигаем - 27
Вроде все ОК должно быть, но по факту список остался на месте и клавиатура закрыла нижние элементы.
Но мы же упорные. Закрываем клавиатуру:
Java
1
00:00:02.774  V  Двигаем - 27
Клавиатура скрылась, список остался как и должен быть.
ОПЯТЬ вызываем клавиатуру:
Java
1
00:00:49.589  V  Двигаем - 27
И о чудо - все работает. Список перемещается. Но почему при первом нажаитии ничего не происходит? Причем неважно, можно ручками список подвигать, туда сюда. Все равно - первый вызов клавиатуры не сдвигает список.
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
18.10.2024, 07:34
Цитата Сообщение от Alex1126 Посмотреть сообщение
Все равно - первый вызов клавиатуры не сдвигает список.
Клавиатуру стоит ловить в GlobalLayoutListener
0
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290
19.10.2024, 22:41  [ТС]
Так событие то отрабатывает. Просто команда результата не дает. Но только при первом срабатывании.

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

Добавлено через 51 минуту
Засунул вызов просто в отдельный поток
Java
1
2
3
4
5
6
7
                new Thread()  {
                    @Override
                    public void run() {
                        runOnUiThread(() -> {
                            messagesRv.scrollToPosition(lastViewPositionRV);
                        });
                    }}.start();
все работает
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
20.10.2024, 07:05
Alex1126, Ну тоже решение,только ресурсоемкое (создание экземпляра Thread)...
проще
Java
1
messagesRv.getHandler().postDelayed(()-> { messagesRv.scrollToPosition(lastViewPositionRV); }, 150);
0
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290
20.10.2024, 14:11  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
проще
ну тогда уж вообще вот так:
Java
1
messagesRv.getHandler().post(()-> { messagesRv.scrollToPosition(lastViewPositionRV); });
Без задержки. И тоже работает. Так в чем причина? В загрузке клавиатуры?
0
436 / 161 / 28
Регистрация: 12.12.2020
Сообщений: 1,290
14.03.2025, 01:44  [ТС]
Вообщем вся эта портянка решается намного проще.
Итак. Краткое содержание предыдущих серий:
Есть recyclerView который отображает логи. Сверху вниз. Внизу самое последнее сообщение. Нужно следующее:
1. При открытии экрана список должен отмотаться в самый низ.
2. При появлении нового сообщение оно добавлялось и список к нему перематывался. Но только если на экране открыто "последнее" сообщение. Если список отмотан "в прошлое", то не перематывать к новому сообщению.
3. При появлении клавиатуры что бы список сдвигался вверх и на экране оставалось внизу то сообщение что было когда клавиатура была закрыта.
Ну и соответственно я высчитывал положения списка при перемотки, отлавливал открытие клавиатуры, сам его (список) передвигал при появлении клавиатуры, запоминал положение и двигал его когда новое сообщение появлялось....

Все это решается просто.
Устанавливаем у LinearLayoutManager свойство reverseLayout в true
Java
1
2
3
4
5
        adapter = new LogAdapter(messages);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getBaseContext());
        linearLayoutManager.setReverseLayout(true);
        messagesRv.setLayoutManager(linearLayoutManager);
        messagesRv.setAdapter(adapter);
И список у нас "переворачивается". Начинает идти снизу вверх. "Проблема" с клавиатурой решается автоматически. Но список идет снизу верх. Это не хорошо. Исправляем:

В адаптере делаем обратный position
Java
1
2
3
4
    public void onBindViewHolder(@NonNull MessageViewHolder holder, int position) {
        int reversePosition = messages.size() - 1 - position;
        Message message = messages.get(reversePosition);
        ...
Ну и еще где у вас если есть position то ее тоже перевернуть надо

Java
1
2
3
4
5
6
7
8
9
10
   @Override
    public int getItemViewType(int position) {
        int reversePosition = messages.size() - 1 - position;
        if (messages.get(reversePosition).isErr) {
            return R.layout.message_err_rv_item;
        }
        else {
            return R.layout.message_rv_item;
        }
    }
Единственный минус этой "схемы" в том что теперь позиции у элементов "плавают", то есть после добавления элемента индексы сдвигаются. И вам надо перерисовывать весь recyclerView после добалвения элемента, то есть
Java
1
adapter.notifyDataSetChanged();
что считается плохим делом, но тут нам реально надо обновить все элементы.

Добавлено через 38 минут
Впринципе если достаточно что бы от клавиатуры список поднимался и опускался, то можно обойтись только

Java
1
linearLayoutManager.setStackFromEnd(true);
Ну и при запуске список в самом внизу будет открыт.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.03.2025, 01:44
Помогаю со студенческими работами здесь

Узнать положение курсора
Здравствуйте, я хочу узнать положение курсора в editText (поле ввода текста), создал обработчик при нажатии вот код: ...

Узнать положение скролла
Привет, мир! Знатоки JS помогите пожалуйста. Как можно узнать на JS положение скролла? На картинке показано, расстояние от точки А до...

Узнать положение курсора в RichEdit?
Как узнать положение курсора - строка, столбец??? VC++

Как узнать положение прокрутки?
Здравствуйте уважаемые форумчане. Нужно узнать как сильно прокрутили HTML страницу. Заранее спасибо.

Узнать положение курсора клавиатуры
Как узнать положение курсора клавиатуры в VB в визуал студио 2022


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru