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

Android:实现子项布局不同的ExpandableListView

实现带EditText末尾子项的ExpandableListView

看起来你正在做一个特殊布局的ExpandableListView——每个组的最后一个子项用EditText,其余用TextView对吧?我来帮你把代码补全并优化,确保逻辑能正常跑起来:

完整的getChildView实现

@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    MainActivity.ViewHolder holder = null;
    final String childText = (String) getChild(groupPosition, childPosition);
    // 这里自己判断是否为组内最后一个子项,比系统传入的isLastChild更可靠
    boolean isLastChildInGroup = childPosition == getChildrenCount(groupPosition) - 1;

    if (convertView == null) {
        holder = new MainActivity.ViewHolder();
        // 根据是否是最后一个子项加载对应布局
        if (isLastChildInGroup) {
            convertView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_edittext, parent, false);
            holder.editText = convertView.findViewById(R.id.child_edittext);
        } else {
            convertView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_textview, parent, false);
            holder.textView = convertView.findViewById(R.id.child_textview);
        }
        convertView.setTag(holder);
    } else {
        holder = (MainActivity.ViewHolder) convertView.getTag();
        // 处理布局复用不匹配的问题:如果复用的布局类型和当前子项不符,重新加载
        boolean currentIsLast = childPosition == getChildrenCount(groupPosition) - 1;
        if ((currentIsLast && holder.editText == null) || (!currentIsLast && holder.textView == null)) {
            convertView = null;
            return getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
        }
    }

    // 绑定数据
    if (isLastChildInGroup) {
        holder.editText.setText(childText);
        // 监听文本变化,实时同步到数据源,避免滚动后输入内容丢失
        holder.editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                _listDataChild.get(groupPosition).set(childPosition, s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });
    } else {
        holder.textView.setText(childText);
    }

    return convertView;
}

配套的ViewHolder定义(放在MainActivity里)

public static class ViewHolder {
    TextView textView;
    EditText editText;
}

对应的布局文件

  1. 普通子项布局(list_item_textview.xml)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/child_textview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:textSize="16sp"/>
  1. 末尾子项布局(list_item_edittext.xml)
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/child_edittext"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:textSize="16sp"
    android:hint="请输入内容"/>

几个关键注意点

  • 判断最后子项的逻辑:别完全依赖系统传入的isLastChild,自己通过childPosition == getChildrenCount(groupPosition) - 1判断更准确。
  • 布局复用的坑:因为有两种不同的子项布局,复用的时候一定要检查布局类型是否匹配,不然会出现空指针或者布局错乱的问题。
  • EditText数据同步:必须给EditText加文本监听,把输入内容实时同步到数据源里,不然滚动列表后输入的内容会丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:19:27