RecyclerView滚动不流畅求助:嵌套ScrollView引发卡顿问题
Yep, you hit the nail on the head—nesting a RecyclerView inside a ScrollView is almost always the culprit here. Let me break down why this causes stuttering, then walk you through the best fixes to get smooth scrolling back while keeping your desired behavior.
Why the Lag Happens
ScrollView forces RecyclerView to measure its height as wrap_content, which means the RecyclerView has to load all its items at once instead of using its core feature: view recycling. This overloads the UI thread, leading to the noticeable lag you’re seeing.
Recommended Fix: Use RecyclerView's Header View
This is the cleanest, most performant solution—it keeps RecyclerView's recycling mechanism intact while letting your header scroll alongside the list items.
Step 1: Create a Separate Header Layout
First, extract your TextView into its own layout file (e.g., header_recruitment.xml):
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/frame1" android:layout_width="match_parent" android:layout_height="300dp" android:text="Recruitment Responses" android:gravity="center" android:textSize="30sp" android:textColor="#fff" android:background="@drawable/bg_rounded1" />
Step 2: Combine Header and Content with ConcatAdapter
AndroidX's ConcatAdapter lets you stitch multiple adapters together, which is perfect for adding a header to your list without messy custom adapter logic.
Create a Header Adapter
class HeaderAdapter(private val headerView: View) : RecyclerView.Adapter<HeaderAdapter.HeaderViewHolder>() { class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder { return HeaderViewHolder(headerView) } override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) { // No data binding needed for a static header } override fun getItemCount(): Int = 1 }
Assemble the Adapters in Your Activity
// Inflate the header view val headerView = layoutInflater.inflate(R.layout.header_recruitment, my_recycler_view, false) // Create your existing content adapter val contentAdapter = YourContentAdapter(yourDataList) // Combine header and content into one adapter val concatAdapter = ConcatAdapter(HeaderAdapter(headerView), contentAdapter) // Set the combined adapter to your RecyclerView my_recycler_view.adapter = concatAdapter
Step 3: Simplify Your Main Layout
Remove the ScrollView entirely—your RecyclerView will handle all scrolling now:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:background="#f9fafc"/> </RelativeLayout>
Alternative (Not Recommended): Fix Nested Scrolling
If you absolutely must keep the ScrollView nesting (e.g., for legacy reasons), you can reduce lag with these tweaks—but note this still disables view recycling, so it’s only viable for small datasets:
- Disable nested scrolling on the
RecyclerViewto avoid scroll conflicts:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/my_recycler_view" android:padding="16dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/frame1" android:background="#f9fafc" android:nestedScrollingEnabled="false"/>
- Add this line in your activity to help optimize measurement:
my_recycler_view.setHasFixedSize(true)
Final Note
Stick with the header view approach—it’s the official Android recommendation, and it’ll keep your scrolling smooth even as your dataset grows.
内容的提问来源于stack exchange,提问作者Rohit DD

