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

Xamarin Android:在ExpandableListView中显示自定义布局

实现ExpandableListView自定义展开项布局(含3个ImageView)

没问题,这需求很常见,我来给你一步步拆解怎么实现:

1. 先写子项(展开后显示的布局)的XML文件

创建一个名为list_item_child.xml的布局文件,就是你想要的带三个横向排列ImageView的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="8dp">

    <ImageView
        android:id="@+id/img_child_1"
        android:layout_width="0dp"
        android:layout_height="80dp"
        android:layout_weight="1"
        android:scaleType="centerCrop"/>

    <ImageView
        android:id="@+id/img_child_2"
        android:layout_width="0dp"
        android:layout_height="80dp"
        android:layout_weight="1"
        android:scaleType="centerCrop"
        android:layout_marginHorizontal="4dp"/>

    <ImageView
        android:id="@+id/img_child_3"
        android:layout_width="0dp"
        android:layout_height="80dp"
        android:layout_weight="1"
        android:scaleType="centerCrop"/>

</LinearLayout>

这里给三个ImageView设置了layout_weight让它们平分宽度,你可以根据需求调整尺寸、间距和缩放模式。

2. 自定义ExpandableListAdapter

核心是继承BaseExpandableListAdapter,并重写关键方法,尤其是getChildView——在这里加载我们的自定义子布局并填充数据:

public class CustomExpandableAdapter extends BaseExpandableListAdapter {

    private Context mContext;
    private List<String> mParentList; // 父项标题列表
    private List<List<Integer>> mChildImageList; // 子项的图片资源ID列表,每个子项对应3个图片ID

    public CustomExpandableAdapter(Context context, List<String> parentList, List<List<Integer>> childImageList) {
        this.mContext = context;
        this.mParentList = parentList;
        this.mChildImageList = childImageList;
    }

    @Override
    public int getGroupCount() {
        return mParentList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        // 如果每个父项展开后只显示一组3张图,直接返回1即可
        return 1;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return mParentList.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mChildImageList.get(groupPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    // 父项的布局,这里用系统默认的简单布局,你也可以自定义
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
        }
        TextView tvParent = convertView.findViewById(android.R.id.text1);
        tvParent.setText(mParentList.get(groupPosition));
        return convertView;
    }

    // 子项布局的关键方法
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_item_child, parent, false);
            holder = new ViewHolder();
            holder.img1 = convertView.findViewById(R.id.img_child_1);
            holder.img2 = convertView.findViewById(R.id.img_child_2);
            holder.img3 = convertView.findViewById(R.id.img_child_3);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        // 获取当前子项的三个图片ID
        List<Integer> imageIds = (List<Integer>) getChild(groupPosition, childPosition);
        holder.img1.setImageResource(imageIds.get(0));
        holder.img2.setImageResource(imageIds.get(1));
        holder.img3.setImageResource(imageIds.get(2));

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true; // 设置子项可点击,不需要的话改成false
    }

    // ViewHolder优化性能
    private static class ViewHolder {
        ImageView img1;
        ImageView img2;
        ImageView img3;
    }
}

3. 在Activity中初始化ExpandableListView

接下来在你的Activity里绑定控件、准备数据并设置Adapter:

public class MainActivity extends AppCompatActivity {

    private ExpandableListView mExpandableListView;
    private CustomExpandableAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mExpandableListView = findViewById(R.id.expandableListView);

        // 准备测试数据:父项标题
        List<String> parentTitles = new ArrayList<>();
        parentTitles.add("第一组图片");
        parentTitles.add("第二组图片");

        // 准备子项图片资源ID,每个父项对应一组3张图
        List<List<Integer>> childImages = new ArrayList<>();
        // 第一组的图片
        List<Integer> group1Images = new ArrayList<>();
        group1Images.add(R.drawable.img1);
        group1Images.add(R.drawable.img2);
        group1Images.add(R.drawable.img3);
        childImages.add(group1Images);
        // 第二组的图片
        List<Integer> group2Images = new ArrayList<>();
        group2Images.add(R.drawable.img4);
        group2Images.add(R.drawable.img5);
        group2Images.add(R.drawable.img6);
        childImages.add(group2Images);

        // 设置Adapter
        mAdapter = new CustomExpandableAdapter(this, parentTitles, childImages);
        mExpandableListView.setAdapter(mAdapter);

        // 可选:默认展开所有父项
        for (int i = 0; i < mAdapter.getGroupCount(); i++) {
            mExpandableListView.expandGroup(i);
        }
    }
}

补充说明

  • 如果是加载网络图片,把setImageResource换成Glide/Picasso等图片加载库的方法即可,比如Glide.with(mContext).load(imageUrl).into(holder.img1)。
  • 要是想给父项也用自定义布局,只需要修改getGroupView方法里加载的布局文件,再绑定对应的控件就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:01:16