RecyclerView设置wrap_content仍出现异常间距,滚动返回后问题显现
Hey there, let's tackle this annoying RecyclerView gap issue you're facing—where scrolling down works fine, but scrolling back up leaves big blank spaces between items, even after setting all parent layouts to wrap_content. Looking at your layout code and the fact you're using a CustomCursorAdapter with CustomRecyclerViewAdapter, here are the most likely fixes:
1. Remove android:animateLayoutChanges="true" from your item layout
I noticed both your CardView and inner ConstraintLayout have android:animateLayoutChanges="true". While this adds nice layout transitions, it plays terribly with RecyclerView's item recycling system. The animation logic can interfere with how the RecyclerView measures item heights during scroll, leading to those weird gaps.
Here's how to adjust your card_item.xml:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/card_parent" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:clickable="true" android:foreground="?android:attr/selectableItemBackground" app:cardCornerRadius="4dp"> <android.support.constraint.ConstraintLayout android:id="@+id/constraint_card_child" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- Rest of your layout here --> </android.support.constraint.ConstraintLayout> </android.support.v7.widget.CardView>
If you still want item animations, use RecyclerView's built-in ItemAnimator instead—it's designed to work with recycling.
2. Fix CursorAdapter data update logic
Since you're using a CursorAdapter, make sure you're updating data correctly. Never just replace the Cursor and call notifyDataSetChanged()—use swapCursor() or changeCursor() instead. These methods handle Cursor lifecycle properly and ensure the RecyclerView's item cache stays in sync with your data.
Also, double-check your onBindViewHolder method: make sure every view that affects item height (like your TableLayout rows) is properly populated with data for the current Cursor position. Empty or incorrectly bound views can cause the RecyclerView to miscalculate item heights during recycling.
3. Force RecyclerView to re-measure items on scroll
If the above fixes don't work, add a scroll listener to trigger a layout refresh when you scroll back to the top. This forces the RecyclerView to re-calculate all item heights, fixing any cached measurement errors:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); if (layoutManager != null && layoutManager.findFirstVisibleItemPosition() == 0) { recyclerView.requestLayout(); } } } });
4. Verify ViewHolder recycling in your CustomAdapter
Check your CustomRecyclerViewAdapter to make sure you're resetting view states properly in onBindViewHolder. For example, if you're dynamically adding rows to the TableLayout, make sure you clear old rows before adding new ones for the current item. Leftover views from recycled ViewHolders can mess up item height calculations.
Bug Demo

内容的提问来源于stack exchange,提问作者Nakamoto

