Keeping the last visible item of a ListView when the size of the ListView changes
What you Want
Last Visible Item Without Keyboard
Last Visible Item With Keyboard
Last Visible Item With larger input
Here is how i did it.
Summary
- Set android:stackFromBottom="true" and android:transcriptMode="alwaysScroll" in your list view
- Set android:windowSoftInputMode="adjustPan" in Activity
- Call adapter.notifyDataSetChanged(); when you add new chats so that the list view will always scroll to the last position
- Set android:inputType="textMultiLine" & android:maxLines="4" in EditText for growing text box
Details
Activity
<activity android:name="MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"></activity>
Chat View
<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>
I think you may want to use AdapterView.getLastVisiblePosition() before displaying the keyboard.
Two solutions here:
- on EditText click
- thanks to an OnScrollListener (and its onScroll function) listening to your ListView
then use the AdapterView.setSelection to jump to this item (or index - 2 or index - 3) after EditText focus.
You can use android:windowSoftInputMode="adjustPan"
in your AndroidManifest.xml as below
<activity android:name="com.example.SimpleListView"
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan" >
This should produce the output you want. Official android documentation .
Optionally you can specify transcript mode(if you are working on some chat feature) for your list view if you want to scroll automatically to the end of listview. You can check the android:transcriptMode="normal"
as well and see if that fits.
A related SO answer. Official android doc.
<ListView
android:id="@+id/comments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="alwaysScroll">
This should solve most of your issues, maybe except for the last one(in the image) which I haven't tested.