Zachowywanie ostatniej widocznej pozycji ListView, gdy zmienia się rozmiar ListView

To, czego chcę, jest proste, przynajmniej myślałem, że będzie proste. Chcę tylko okno, w którym EditText jest na dole ekranu, a reszta miejsca jest wypełniona ListView. Niestety nie zadziałało tak, jak się spodziewałem. To, czego chcę, to poniższy obraz. Czy jest jakiś łatwy sposób, aby to zrobić w XML, czy powinienem napisać jakiś specjalny kod do tego? What I want

Mój Problematyczny Kod Źródłowy Androida.
<?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 >
Author: Martin Stone, 2012-02-19

12 answers

Czego chcesz

Ostatni Widoczny Element Bez Klawiatury

Ostatni Widoczny Element Bez Klawiatury

Ostatni Widoczny Element Z Klawiaturą

Ostatni Widoczny Element Z Klawiaturą

Ostatni widoczny element z większym wejściem

Ostatni widoczny element z większym wejściem

Oto Jak to zrobiłem.

Podsumowanie

  • Ustaw android: stackFromBottom= "true" i android: transcriptMode = "alwaysScroll" w widoku listy
  • zestaw android: windowSoftInputMode= "adjustPan" in Activity
  • Call adapter.notifyDataSetChanged (); Po dodaniu nowych czatów, aby Widok listy zawsze przewijał się do ostatniej pozycji
  • Set android: inputType= "textMultiLine" & android: maxLines= " 4 " in EditText for growing text box

Szczegóły

Działalność

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

Widok Czatu

<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>

 19
Author: sooraj.e,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 07:28:01

Myślę, że możesz użyć AdapterView.getLastVisiblePosition () przed wyświetlaniem klawiatury.

Dwa rozwiązania tutaj:

  • na EditText kliknij
  • dzięki Onscrollistener (i jego funkcji onScroll) słuchanie ListView

Następnie użyj AdapterView .setSelection to jump to this item (or index - 2 or index - 3) after EditText focus.

 7
Author: Gorcyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-22 16:14:29

Możesz użyć android:windowSoftInputMode="adjustPan" w AndroidManifest.xml jak poniżej

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

To powinno wytworzyć dane wyjściowe, które chcesz. Oficjalna dokumentacja Androida .

Opcjonalnie możesz określić tryb transkrypcji (jeśli pracujesz nad jakąś funkcją czatu) dla widoku listy, jeśli chcesz automatycznie przewijać listę na koniec listview. Możesz też sprawdzić android:transcriptMode="normal" i sprawdzić, czy to pasuje.

A related więc odpowiedz . Oficjalny android doc .

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

To powinno rozwiąż większość swoich problemów, może poza ostatnim (Na zdjęciu), którego nie testowałem.

 3
Author: jaga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:13

Wystarczy przesłać metodę ListView#onSizeChanged (int w, int h, int oldw, int oldh) jak poniżej: PS: wysokość ListView nie może być 0 w każdej chwili, jeśli może 0, nie działa.

@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);
    }
}
 3
Author: Presley Zheng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 02:54:34

Otrzymałem to samo zachowanie, które trzeba dodać do Activity deklaracji w manifeście android:windowSoftInputMode="adjustResize" i do ListView deklaracji android:transcriptMode="normal". Zarówno dla Klawiatury, jak i zmiany orientacji.

 2
Author: mbarrben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 16:31:01

Ja też potrzebuję tej funkcjonalności. Oto moja próba, ale to nie do końca działa -- przewijanie jest nieco nieregularne (nie zawsze kończy się tam, gdzie powinno) i przeszkadza w zachowaniu pozycji przewijania podczas obracania ekranu.

@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);
        }
    }
};
 1
Author: Martin Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-12 17:57:09

Możesz to zrobić poprzez xml:

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

Układanie od dołu spowoduje domyślnie przewinięcie ListView w dół, ustawienie wagi ListView wypełni całą możliwą przestrzeń w nadrzędnym pionowym LinearLayout.

 1
Author: alexei burmistrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-23 13:25:50

Stworzyłem silnik układu dla Androida, który pozwala słuchać ukrytych i widocznych zmian stanu klawiatury (wśród wielu innych podstawowych funkcji). Ta Biblioteka jest dostępna pod adresem http://phil-brown.github.io/AbLE/.

Po prostu dodaj jar do katalogu libs (Utwórz ten folder, jeśli nie istnieje) i zamiast dziedziczyć z Activity, Dziedzicz z AbLEActivity. Następnie Nadpisz metody onKeyboardShown i onKeyboardHidden, a w nich możesz animować Widok zawartości w górę lub w dół jako potrzebne:

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

@Override
public void onKeyboardHidden() {
    //animate down
}
 1
Author: Phil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 19:23:32

Mam nadzieję, że to ci pomoże ....

Przypuśćmy, że wiesz, kiedy dane Listy się zmieniły, możesz ręcznie powiedzieć liście, aby przewijała się na dół, ustawiając wybór listy na ostatni wiersz. Coś takiego:

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) ;
        }
    });
}

Lub możesz też spróbować tego ..u mnie działa:

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);    
    }
});
 0
Author: Nipun Gogia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 09:27:30
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);
Mam nadzieję, że to rozwiąże twój problem.
 0
Author: Suresh Pichuka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-05 07:34:09

W Twoim Listadapterze możesz zrobić coś takiego:

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

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

    ....

W ten sposób zawsze otrzymasz ostatnią pozycję na liście jako pole tekstowe.

 -1
Author: Snicolas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 17:49:01

Musisz ustawić pozycję wyboru... Ale-w dziwny sposób, nie bardzo rozumiem dlaczego-musisz to zrobić z post ()

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

Więc możesz dodać Texttwatcher dla swojego editText i możesz wywołać tę metodę... Więc Twoja lista będzie przewijać do dołu.

 -1
Author: yahya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 08:35:14