Make last item / ViewHolder in RecyclerView fill the rest of the screen or have a minimum height

I am struggling with RecyclerView. I use the recycler view to display the details of my model class.

//My model class MyModel { String name; Double latitude; Double longitude; Boolean isOnline; ... } 

Since some of the values ​​may be missing, I use RecyclerView with custom view types (one of which represents each value of my model).

 //Inside my custom adapter public void setModel(T model) { //Reset values itemCount = 0; deviceOfflineViewPosition = -1; mapViewPosition = -1; //If device is offline, add device offline item if (device.isOnline() == null || !device.isOnline()) { deviceOfflineViewPosition = itemCount; itemCount++; } //Add additional items if necessary ... //Always add the map as the last item mapViewPosition = itemCount; itemCount++; notifyDataSetChanged(); } @Override public int getItemViewType(int position) { if (position == deviceOfflineViewPosition) { return ITEM_VIEW_TYPE_OFFLINE; } else if (position == mapViewPosition) { return ITEM_VIEW_TYPE_MAP; } else if (...) { //Check for other view types } } 

With RecyclerView, I can easily determine at runtime which values ​​are available and add the corresponding elements to the RecyclerView data source. I just used the code, but my model has a lot more values, and I have a lot more types of views.

The last element in RecyclerView is always a map and always present. Even if in my model there is no value, at least there will be one element, a map.

PROBLEM . How can I make the last element in RecyclerView fill the remaining space on the screen and also get the minimum value. The size should be what it’s ever cost: the remaining space or the minimum height. For example:

  • The model has several values, which in total occupy 100dp of a 600dp screen β†’ the map height should be 500dp
  • The model has many values, which in total occupy 500dp of the screen 600dp β†’ map heigh should be the minimum value of 200dp
  • The model does not matter β†’ the map fills the entire screen

enter image description here

+10
android adapter google-maps android-recyclerview android-adapter
source share
1 answer

You can find the remaining space in the RecyclerView after placing the last item and add that remaining space to the minHeight last item.

 val isLastItem = getItemCount() - 1 == position if (isLastItem) { lastItemView.doOnLayout { val recyclerViewHeight = recyclerView.height val lastItemBottom = lastItemView.bottom val heightDifference = recyclerViewHeight - lastItemBottom if (heightDifference > 0) { lastItemView.minimumHeight = lastItemView.height + heightDifference } } } 

In onBindHolder check if the item is the last using getItemCount() - 1 == position . If this is the last element, find the height difference by subtracting the height of the recyclerView with the last bottom lastItem ( getBottom() gives you the lowest pixel of the view relative to its parent. In this case, our parent is RecyclerView ).

Note. This code is Kotlin, and the doOnLayout function is from Android KTx . Also your RecyclerView height must be match_parent for this to work (I think it is obvious).

If the difference is greater than 0, add it to the current height of the last view and set it to minHeight . We set this as minHeight instead of setting it directly as height to support dynamic content changes for the last view.

0
source share

All Articles