I made a RecyclerView inside a NavigationView with a custom first item as an equivalent to ListView's addHeaderView(). On the bottom part of that header layout I placed an EditText so that I can filter out the list below.
What I wanted to do was to scroll the RecyclerView all the way up until the EditText would be the topmost item whenever the EditText gains focus. However if my item count is small enough that it wouldn't be able to fill-up the entire height of the NavigationView, the RecyclerView refuses to scroll all the way up and thus showing a bit more of the header other than the EditText. As an added problem, even if the list is large enough, it stills scrolls back down once I start filtering the list items.
How can I force my RecyclerView to still scroll all the way up even if I don't have enough items in to fill the height of my view so that the rest of my header do not take a peek?
Here's a visualization of what I'm trying to achieve:
_______________
| HEADER LINE 1 |
| HEADER LINE 2 |
| HEADER LINE 3 |
| ------------- |
| Search box |
| ------------- |
| List item 1 |
| List item 2 |
| List item 3 |
---------------
Expected behavior when I focus on the search box:
_______________
| ------------- |
| Search box | <- becomes the topmost item. I can already achieve this
| ------------- | with RecyclerView.smoothScrollBy(dx, dy)
| List item 1 | except when the list is small enough (see below)
| List item 2 |
| List item 3 |
| List item 4 |
| | <- empty space is okay and is desired if dataset
| | is small enough
---------------
What actually happens:
_______________
| HEADER LINE 2 | <- the header is 'bleeding' on top
| HEADER LINE 3 |
| ------------- |
| Search box | <- search box cannot take the topmost spot
| ------------- | as the recycler tries to position itself to fill in
| List item 1 | the bottom part with items
| List item 2 |
| List item 3 |
| List item 4 | <- items are pushed down to the bottom to fill
--------------- in the space
Here's a snippet of my NavigationView xml (just your typical setup):
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/drawer_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.NavigationView>
ViewHolder with custom header here (RecyclerView Adapter):
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == HEADER) {
return new HeaderHolder(mHeaderView);
} else {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ItemViewHolder(v);
}
}
The drawer header is just an xml layout I inflated in the main activity (I assigned listeners and animations there) and passed on to my RecyclerView adapter via a setHeaderView(View header) I made.