Подтвердить что ты не робот

Сохранение последнего видимого элемента ListView при изменении размера ListView

Я хочу просто, ну, по крайней мере, я думал, что это будет просто. Я просто хочу окно, где EditText находится в нижней части экрана, а остальная часть пространства заполняется ListView. К сожалению, это не сработало, как я ожидал. Я хочу следующее изображение. Есть ли простой способ сделать это в XML, или я должен написать для этого специальный код? What I want

Мой проблемный исходный код Android.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
    android:id="@+id/demolist"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
     >
</ListView>
    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:layout_weight="0">
    </EditText>
</LinearLayout >
4b9b3361

Ответ 1

Что вы хотите

Последний видимый элемент без клавиатуры

Last Visible Item Without Keyboard

Последний видимый элемент с клавиатурой

Last Visible Item With Keyboard

Последний видимый элемент с большим входом

Last Visible Item With larger input

Вот как я это сделал.

Резюме

  • Установите android: stackFromBottom = "true" и android: transcriptMode = "alwaysScroll" в вашем представлении списка
  • Установить android: windowSoftInputMode = "adjustPan" в действии
  • Вызов adapter.notifyDataSetChanged();, когда вы добавляете новые чаты, чтобы вид списка всегда прокручивался до последней позиции.
  • Установите android: inputType = "textMultiLine" и android: maxLines = "4" в EditText для расширения текстового поля

Подробнее

активность

<activity android:name="MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"></activity>

Просмотр чата

<RelativeLayout
    android:id="@+id/chat_header"
    android:layout_width="fill_parent"
    android:layout_height="40dp"
    android:padding="3dp" >

    <Button
        android:id="@+id/btnBackChat"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentLeft="true"
        android:background="@drawable/back_button" />

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/btnBackChat"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <ImageView
        android:id="@+id/imgViewProfileChat"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentRight="true"
        />
</RelativeLayout>

<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/form"
    android:layout_below="@+id/chat_header"
    android:stackFromBottom="true"
    android:transcriptMode="alwaysScroll"/>

<RelativeLayout
    android:id="@+id/form"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:orientation="vertical" >

    <ImageButton
        android:id="@+id/btnAttach"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/attach"
        android:src="@drawable/attach_icon" />

    <EditText
        android:id="@+id/txtChat"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/btnSend"
        android:layout_toRightOf="@+id/btnAttach"
        android:inputType="textMultiLine"
        android:maxLines="4" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="@string/send" />
</RelativeLayout>

Ответ 2

Я думаю, вы можете использовать AdapterView.getLastVisiblePosition() перед отображением клавиатуры.

Два решения здесь:

  • в EditText нажмите
  • благодаря функции OnScrollListener (и ее функции onScroll), которая прослушивает ваш ListView

затем используйте AdapterView.setSelection, чтобы перейти к этому элементу (или индексу - 2 или индексу - 3) после фокусировки EditText.

Ответ 3

Вы можете использовать android:windowSoftInputMode="adjustPan" в вашем AndroidManifest.xml, как показано ниже

 <activity android:name="com.example.SimpleListView"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustPan" >

Это даст результат, который вы хотите. Официальная документация по Android.

При желании вы можете указать режим транскрипции (если вы работаете над какой-либо функцией чата) для своего списка, если вы хотите автоматически прокручивать до конца списка. Вы также можете проверить android:transcriptMode="normal" и посмотреть, подходит ли это.

Связанный ответ SO > . Официальный android doc.

<ListView
android:id="@+id/comments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="alwaysScroll">

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

Ответ 4

Просто переопределите метод ListView # onSizeChanged (int w, int h, int oldw, int oldh), как показано ниже: PS: Ваша высота ListView не может быть 0 в любое время, если она может 0, не работает.

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (getChildCount() == 0) {
        return;
    }
    final int lastVisiblePosition = getLastVisiblePosition();
    int firstVisiblePosition = getFirstVisiblePosition();

    View last = getChildAt(lastVisiblePosition - firstVisiblePosition);
    int top = last.getTop();
    final int newTop = top + (h - oldh);
    Log.d(getClass().getSimpleName(), "onSizeChanged(" + w + ", " + h + ", " + oldw + ", " + oldh + ")");
    if (mFocusSelector == null) {
        mFocusSelector = new FocusSelector();
    }
    post(mFocusSelector.setup(lastVisiblePosition, newTop));
    super.onSizeChanged(w, h, oldw, oldh);
}

private class FocusSelector implements Runnable {
    private int mPosition;
    private int mPositionTop;

    public FocusSelector setup(int position, int top) {
        mPosition = position;
        mPositionTop = top;
        return this;
    }

    public void run() {
        setSelectionFromTop(mPosition, mPositionTop);
    }
}

Ответ 5

Я действительно получил то же поведение, которое вам нужно, добавив в объявление Activity в манифесте android:windowSoftInputMode="adjustResize" и в объявление ListView android:transcriptMode="normal". Для изменения клавиатуры и ориентации.

Ответ 6

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

@Override
public void onResume() {
    super.onResume();
    getListView().addOnLayoutChangeListener(stickyLastItemHandler);
}

@Override
public void onPause() {
    super.onPause();
    getListView().removeOnLayoutChangeListener(stickyLastItemHandler);
}

View.OnLayoutChangeListener stickyLastItemHandler = new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v,
            int left, int top, int right, int bottom,
            int oldLeft, int oldTop, int oldRight, int oldBottom) {

        final int heightChange = (bottom - top) - (oldBottom - oldTop);
        if (heightChange != 0) {
            ((AbsListView)v).smoothScrollBy(-heightChange, 1000);
        }
    }
};

Ответ 7

Вы можете сделать это через xml:

<ListView
    android:stackFromBottom="true"
    android:layout_height=0dp
    android:layout_weight=1 />

Укладка вниз приведет к тому, что ListView будет прокручиваться по умолчанию, установка веса ListView заполнит все возможное пространство внутри родительского вертикального LinearLayout.

Ответ 8

Я создал механизм компоновки для Android, который позволяет слушать скрытые и видимые изменения клавиатуры (среди многих других основных функций). Эта библиотека доступна по адресу http://phil-brown.github.io/AbLE/.

Просто добавьте jar в каталог libs (создайте эту папку, если она не существует), а вместо наследования с Activity наследуйте от AbLEActivity. Затем переопределите методы onKeyboardShown и onKeyboardHidden, и в них вы можете анимировать представление своего контента вверх или вниз по мере необходимости:

@Override
public void onKeyboardShown() {
    //animate up
}

@Override
public void onKeyboardHidden() {
    //animate down
}

Ответ 9

просто проверьте это: надеюсь, это поможет вам....

Предположим, что вы знаете, когда данные списка изменились, вы можете вручную указать списку для прокрутки вниз, установив список в последнюю строку. Что-то вроде этого:

private void scrollMyListViewToBottom() {
    myListView.post(new Runnable() {
        @Override
        public void run() {
            // Select the last row so it will scroll into view...
            myListView.setSelection(myListAdapter.getCount() - 1) ;
        }
    });
}

или вы также можете попробовать это.. это работает для меня:

ChatAdapter adapter = new ChatAdapter(this);

ListView lview = (ListView) findViewById(R.id.chatList);
lview .setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lview .setAdapter(adapter);

adapter.registerDataSetObserver(new DataSetObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
        lv.setSelection(adapter.getCount() - 1);    
    }
});

Ответ 10

Follow these steps
--------------------
1. Update your activity in AndroidManifest.xml file like below
<activity
            android:name=".MyListActivity"
            android:windowSoftInputMode="adjustResize" />

2. Set your list view with like below.
mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
mListView.setStackFromBottom(true);

Я надеюсь, что это решит вашу проблему.

Ответ 11

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

   public View getView(int position, View convertView, ViewGroup parent) {

//buttonMore
if( position >= super.getCount()  )
      return textField ;

    ....

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

Ответ 12

Вам нужно установить позицию выбора... Но - странным образом, я действительно не понимаю, почему - вам нужно сделать это с помощью post()

public void ScrollToLast() {
    yourList.clearFocus();
    yourList.post(new Runnable() {
        @Override
        public void run() {
            yourList.setSelection(items.size() - 1);
        }
    });
}

Итак, вы можете добавить TextWatcher для своего editText, и вы можете вызвать этот метод там... Таким образом, ваш список будет прокручиваться донизу.