You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中嵌套多ListView的NestedScrollView无法滚动问题

解决NestedScrollView嵌套ListView无法滚动的问题

问题原因

你当前布局中,多个ListView嵌套在NestedScrollView里,这两个组件都自带滚动机制,会触发滚动事件冲突,导致无法正常滚动。同时ListView设置android:layout_height="wrap_content"时,会展开所有列表项,但NestedScrollView的滚动逻辑和ListView的触摸事件处理互相干扰,最终出现滚动失效的情况。

解决方案

方案一:用RecyclerView实现分组列表(推荐,符合Android最佳实践)

这种方式彻底避免嵌套滚动冲突,同时性能更优。

1. 添加RecyclerView依赖

在Module级别的build.gradle中添加依赖:

dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.2"
}

2. 修改布局文件

替换原有嵌套结构,仅保留一个RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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=".ui.home.HomeFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/grouped_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:padding="10dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

3. 创建数据模型

定义标题项和列表项两种类型:

sealed class GroupItem {
    data class Header(val title: String) : GroupItem()
    data class ListItem(val content: String) : GroupItem()
}

4. 实现RecyclerView适配器

class GroupedAdapter(private val itemList: List<GroupItem>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        private const val TYPE_HEADER = 0
        private const val TYPE_ITEM = 1
    }

    override fun getItemViewType(position: Int): Int {
        return when (itemList[position]) {
            is GroupItem.Header -> TYPE_HEADER
            is GroupItem.ListItem -> TYPE_ITEM
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return if (viewType == TYPE_HEADER) {
            val view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
            HeaderViewHolder(view)
        } else {
            val view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
            ItemViewHolder(view)
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is HeaderViewHolder -> {
                val header = itemList[position] as GroupItem.Header
                holder.titleTextView.text = header.title
                holder.titleTextView.setTypeface(null, Typeface.BOLD)
            }
            is ItemViewHolder -> {
                val item = itemList[position] as GroupItem.ListItem
                holder.contentTextView.text = item.content
            }
        }
    }

    override fun getItemCount() = itemList.size

    class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleTextView: TextView = itemView.findViewById(android.R.id.text1)
    }

    class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val contentTextView: TextView = itemView.findViewById(android.R.id.text1)
    }
}

5. 在Fragment中初始化数据和RecyclerView

class HomeFragment : Fragment() {

    private lateinit var recyclerView: RecyclerView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_home, container, false)
        recyclerView = view.findViewById(R.id.grouped_recycler_view)
        recyclerView.layoutManager = LinearLayoutManager(context)
        
        // 构建分组数据
        val sportsArray = resources.getStringArray(R.array.sports_array)
        val itemList = mutableListOf<GroupItem>()
        repeat(4) { index ->
            itemList.add(GroupItem.Header("Header ${index + 1}"))
            sportsArray.forEach { sport ->
                itemList.add(GroupItem.ListItem(sport))
            }
        }
        
        recyclerView.adapter = GroupedAdapter(itemList)
        return view
    }
}

方案二:临时修复现有布局(不推荐,仅适合小数据量场景)

如果暂时不想重构,可通过禁用ListView自身滚动解决冲突,但数据量大时会导致性能问题:
给每个ListView添加android:nestedScrollingEnabled="false"属性,示例:

<ListView
    android:id="@+id/list1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:entries="@array/sports_array"
    android:nestedScrollingEnabled="false" />

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 20:36:23