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

Kotlin中如何在ExpandableListView头部正确显示子项数量

Hey there, let's fix that ExpandableListView header count issue you're dealing with. I’ve walked through your problem context, and here’s a step-by-step solution to get those group headers showing the correct number of child items, paired with your API-fetched today/tomorrow/upcoming tasks.


1. First, Let's Pinpoint the Likely Issues

Most often, the wrong count in group headers comes from:

  • Incorrect mapping of API data into grouped lists
  • A bug in the adapter's getChildrenCount() method returning fixed values instead of real child counts
  • Mistakes when binding the count value to the header TextView

2. Step-by-Step Fix

2.1 Ensure Your API Data is Grouped Correctly

First, let's confirm your API response model and data parsing. Assume your API returns data like this:

// API Response Models
data class TaskResponse(
    val todayTasks: List<Task>,
    val tomorrowTasks: List<Task>,
    val upcomingTasks: List<Task>
)

data class Task(
    val id: String,
    val title: String,
    val description: String
)

In your Activity, after fetching the API data, restructure it into a format that's easy for the ExpandableListView adapter to use:

// Inside your Activity's API success callback
val groupedTasks = listOf(
    "今日任务" to apiResponse.todayTasks,
    "明日任务" to apiResponse.tomorrowTasks,
    "未来任务" to apiResponse.upcomingTasks
)

2.2 Fix the ExpandableListAdapter

The adapter needs to reliably return child counts and bind them to the header. Here's the corrected adapter code:

class TaskExpandableAdapter(
    private val context: Context,
    private val groupedTasks: List<Pair<String, List<Task>>>
) : BaseExpandableListAdapter() {

    // Return total number of groups (3: today/tomorrow/upcoming)
    override fun getGroupCount(): Int = groupedTasks.size

    // Critical: Return REAL child count for the selected group
    override fun getChildrenCount(groupPosition: Int): Int = groupedTasks[groupPosition].second.size

    override fun getGroup(groupPosition: Int): Any = groupedTasks[groupPosition].first

    override fun getChild(groupPosition: Int, childPosition: Int): Any = groupedTasks[groupPosition].second[childPosition]

    override fun getGroupId(groupPosition: Int): Long = groupPosition.toLong()

    override fun getChildId(groupPosition: Int, childPosition: Int): Long = childPosition.toLong()

    override fun hasStableIds(): Boolean = true

    // Bind group header with correct count
    override fun getGroupView(
        groupPosition: Int,
        isExpanded: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        val headerView = convertView ?: LayoutInflater.from(context)
            .inflate(R.layout.group_header_layout, parent, false)

        // Get header views
        val groupTitleTv = headerView.findViewById<TextView>(R.id.tv_group_title)
        val childCountTv = headerView.findViewById<TextView>(R.id.tv_child_count)
        val expandIconIv = headerView.findViewById<ImageView>(R.id.iv_expand_icon)

        // Set title and count
        val groupData = groupedTasks[groupPosition]
        groupTitleTv.text = groupData.first
        childCountTv.text = "(${groupData.second.size})"

        // Update expand/collapse icon (optional)
        expandIconIv.setImageResource(
            if (isExpanded) R.drawable.ic_collapse_arrow else R.drawable.ic_expand_arrow
        )

        return headerView
    }

    // Bind child task items
    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        val childView = convertView ?: LayoutInflater.from(context)
            .inflate(R.layout.task_child_item, parent, false)

        val task = getChild(groupPosition, childPosition) as Task
        childView.findViewById<TextView>(R.id.tv_task_title).text = task.title
        childView.findViewById<TextView>(R.id.tv_task_desc).text = task.description

        return childView
    }

    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean = true
}

2.3 Initialize Adapter Correctly in Activity

Make sure you set up the adapter after the API data is fetched:

class TaskListActivity : AppCompatActivity() {
    private lateinit var expandableListView: ExpandableListView
    private lateinit var taskAdapter: TaskExpandableAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_task_list)

        expandableListView = findViewById(R.id.expandable_list_task)
        fetchTasksFromApi()
    }

    private fun fetchTasksFromApi() {
        // Replace with your actual API call (Retrofit, OkHttp, etc.)
        val apiCall = /* Your API request logic */
        apiCall.enqueue(object : Callback<TaskResponse> {
            override fun onResponse(call: Call<TaskResponse>, response: Response<TaskResponse>) {
                response.body()?.let { taskData ->
                    val groupedTasks = listOf(
                        "今日任务" to taskData.todayTasks,
                        "明日任务" to taskData.tomorrowTasks,
                        "未来任务" to taskData.upcomingTasks
                    )
                    taskAdapter = TaskExpandableAdapter(this@TaskListActivity, groupedTasks)
                    expandableListView.setAdapter(taskAdapter)

                    // Optional: Expand all groups by default
                    for (i in 0 until taskAdapter.groupCount) {
                        expandableListView.expandGroup(i)
                    }
                }
            }

            override fun onFailure(call: Call<TaskResponse>, t: Throwable) {
                // Handle API failure
            }
        })
    }
}

3. Troubleshooting If Issues Persist

If the count still doesn't show correctly, check these:

  • Verify your API response is returning the correct task lists (no empty lists where they shouldn't be)
  • Double-check that getChildrenCount() isn't returning a hardcoded value (e.g., return 2 instead of the real list size)
  • Ensure the header layout's TextView IDs match what you're using in the adapter
  • If you're refreshing data later, call taskAdapter.notifyDataSetChanged() to update the views

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:04:55