You might achieve this with setSelectionFromTop()
and by overriding onSizeChanged()
in a custom listview. In your layout, you should have a RelativeLayout
has a parent container and place the listview above the edittext.
By creating your own listview and overriding onSizeChange()
, you will be able to get the last visible item's position before the listview resizing and get its new height, in order to finally set the "previous" position of the list with an offset of its height.
How it works: Your list will place the previous last visible item at its top and you will add the pixels to scroll it at its bottom, just above your edittext.
To override the method and display it with an offset, do as follows:
@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
is a little workaround, because I didn't find how to get the last item's height before that onSizeChanged is called. Then, in the case of your listview contains many types of items (without the same height), I prefer to get the selected height when an event occurs, just before the SoftKeyboard opens up.
So in the custom listview, you have this global variable:
int lastItemHeight = 0;
And in the activity (or fragment, whatever), you update this value in 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();
}
}
});
}
});
Note: there is another possible solution but you have to set android:stackFromBottom="true"
on the listview, which stackes its content from the bottom. Instead, this solution here can display a specific item without forcing the content to start from the bottom, with the default listview's behaviour.
Second note: (just in case) don't forget to add android:windowSoftInputMode="adjustResize"
in the manifest.