сохранение нижнего элемента ListView видимым при появлении клавиатуры - PullRequest
5 голосов
/ 29 ноября 2011

У меня есть LinearLayout, содержащий как ListView, так и EditText.Когда экранная клавиатура запускается при прикосновении к EditText, размер ListView изменяется так, что остаются видны только несколько верхних элементов.

Контекст, в котором используется ListView, имеет нижнююнекоторые элементы более релевантны визуально, чем верх, и поэтому я бы хотел, чтобы его размер был изменен так, чтобы было видно нижнее, а не верхнее.Любые указатели?

(Кстати, текущее исправление, которое я использую, включает в себя использование smoothScrollToPosition, но из-за медленной прокрутки это нежелательно)

Ответы [ 3 ]

1 голос
/ 03 апреля 2014

Сегодня утром я решил похожую проблему и подумал, что опубликую свой результат здесь для пользы будущих искателей. Моя проблема заключалась в том, что прокрутка к нижней части не помогала, поскольку я вызывал ее до того, как представление фактически изменило размер. Решение? Подождите, пока он не изменит размер, используя GlobalLayoutListener

Шаги: 1) реализовать следующий метод в активности, содержащей просмотр списка

public void scrollToBottom(){
    //I think this is supposed to run on the UI thread
    listView.setSelection(mAdapter.getCount() - 1);
}

2) создать следующий класс

public class OnGlobalLayoutListenerWithScrollToBottom implements OnGlobalLayoutListener{

    private boolean scroll;
    private OnScrollToBottomListener listener;
    public interface OnScrollToBottomListener{
        public void scrollToBottom();
    }

    public OnGlobalLayoutListenerWithScrollToBottom(OnScrollToBottomListener listener){
        this.listener = listener;
    }

    @Override
    public void onGlobalLayout() {
        if(scroll){
            listener.scrollToBottom();
            scroll = false;
        }
    }

    /**
     * Lets the listener know to request a scroll to bottom the next time it is layed out
     */
    public void scrollToBottomAtNextOpportunity(){
        scroll = true;
    }

};

3) В своей деятельности реализуйте интерфейс из этого класса. Затем в своей деятельности создайте экземпляр этого OnGlobalLayoutListener и установите его в качестве прослушивателя для вашего listView

    //make sure your class implements OnGlobalLayoutListenerWithScrollToBottom.OnScrollToBottomListener
    listViewLayoutListener = new OnGlobalLayoutListenerWithScrollToBottom(this);
    listView.getViewTreeObserver().addOnGlobalLayoutListener(listViewLayoutListener);

4) Прежде чем вносить изменения, которые повлияют на размер представления списка, такие как отображение и скрытие других представлений или добавление содержимого в представление списка, в своей деятельности просто сообщите слушателю макета прокрутку при следующей возможности

listViewLayoutListener.scrollToBottomAtNextOpportunity();
0 голосов
/ 12 декабря 2015

Этого можно достичь с помощью setSelectionFromTop() и переопределением onSizeChanged() в пользовательском просмотре списка. В вашем макете у вас должен быть RelativeLayout есть родительский контейнер и поместите представление списка над текстом редактирования.

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

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

Чтобы переопределить метод и отобразить его со смещением, выполните следующие действия:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    // get last visible item's position before resizing
    int lastPosition = super.getLastVisiblePosition();
    // call the super method to resize the listview
    super.onSizeChanged(w, h, oldw, oldh);
    // after resizing, show the last visible item at the bottom of new listview's height
    super.setSelectionFromTop(lastPosition, (h - lastItemHeight));
}

lastItemHeight - это небольшой обходной путь, потому что я не нашел, как получить высоту последнего элемента до вызова onSizeChanged. Затем, если ваш список содержит много типов элементов (без одинаковой высоты), я предпочитаю получать выбранную высоту, когда происходит событие, непосредственно перед открытием SoftKeyboard.

Итак, в пользовательском просмотре списка есть глобальная переменная:

int lastItemHeight = 0;

И в действии (или фрагменте, что угодно) вы обновляете это значение в OnClickListener:

edittext.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // set a new Thread
        listview.post(new Runnable() {
            @Override
            public void run() {
                // get last visible position of items
                int lastPosition = listview.getLastVisiblePosition() - 1;
                // if the view's last child can be retrieved
                if ( listview.getChildAt(lastPosition) != null ) {
                    // update the height of the last child in custom listview
                    listview.lastItemHeight = listview.getChildAt(lastPosition).getHeight();
                }
            }
        });
    }
});

Примечание: есть и другое возможное решение , но вы должны установить android:stackFromBottom="true" в просмотре списка, который складывает его содержимое снизу. Вместо этого данное решение может отображать определенный элемент без принудительного запуска контента снизу, с поведением списка по умолчанию.

Второе примечание: (на всякий случай) не забудьте добавить android:windowSoftInputMode="adjustResize" в манифест.

0 голосов
/ 29 ноября 2011

Вы должны добавить этот атрибут в манифест для вашей деятельности и выбрать правильное значение для него (возможно, вы выберете «AdjustResize»):

<activity android:name="package.yourActivity" android:windowSoftInputMode="adjustResize"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...