父子项均含多字段时,如何用JSON数据填充ExpandableListView?
嘿,这个需求其实挺常见的,完全可以实现!我来一步步给你讲清楚怎么做:
1. 先定义数据模型类
咱们先把父项和子项的数据结构定下来,因为两者都有nome和comentario字段,父项还多了一个子项列表resp。分开定义两个模型类会更清晰,避免混淆:
// 父项数据模型 public class ParentComment { private String nome; private String comentario; private List<ChildComment> resp; // 构造方法、getter和setter必须齐全 public ParentComment(String nome, String comentario, List<ChildComment> resp) { this.nome = nome; this.comentario = comentario; this.resp = resp; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getComentario() { return comentario; } public void setComentario(String comentario) { this.comentario = comentario; } public List<ChildComment> getResp() { return resp; } public void setResp(List<ChildComment> resp) { this.resp = resp; } } // 子项数据模型 public class ChildComment { private String nome; private String comentario; public ChildComment(String nome, String comentario) { this.nome = nome; this.comentario = comentario; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getComentario() { return comentario; } public void setComentario(String comentario) { this.comentario = comentario; } }
2. 解析你的JSON数据
接下来把你提供的JSON字符串转换成上面定义的模型列表。推荐用Gson库来解析,方便又省心。如果还没加依赖,先在build.gradle里添加:
dependencies { implementation 'com.google.code.gson:gson:2.10.1' }
然后解析代码如下:
// 把你的JSON字符串替换成实际的数据源 String jsonString = "[ { \"nome\": \"Carlos\", \"comentario\": \"Esse dia foi show\", \"resp\": [ ] }, { \"nome\": \"Andre\", \"comentario\": \"Acho que não precisava disso\", \"resp\": [ { \"nome\": \"inutil\", \"comentario\": \"Sempre assim\" }, { \"nome\": \"Roberto\", \"comentario\": \"Se não estivessem fazendo nada errado,...\" } ] } ]"; Gson gson = new Gson(); Type listType = new TypeToken<List<ParentComment>>(){}.getType(); List<ParentComment> parentCommentList = gson.fromJson(jsonString, listType);
3. 自定义ExpandableListAdapter
核心部分来了,咱们要写一个自定义适配器,继承BaseExpandableListAdapter,重写关键方法来加载自定义布局并设置多字段数据:
public class CustomExpandableListAdapter extends BaseExpandableListAdapter { private Context mContext; private List<ParentComment> mParentList; public CustomExpandableListAdapter(Context context, List<ParentComment> parentList) { mContext = context; mParentList = parentList; } @Override public int getGroupCount() { return mParentList.size(); } @Override public int getChildrenCount(int groupPosition) { return mParentList.get(groupPosition).getResp().size(); } @Override public Object getGroup(int groupPosition) { return mParentList.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return mParentList.get(groupPosition).getResp().get(childPosition); } @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) { ParentComment parentComment = (ParentComment) getGroup(groupPosition); // 复用布局提升性能 if (convertView == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.group_item, parent, false); } // 找到布局里的TextView,设置数据 TextView tvNome = convertView.findViewById(R.id.tv_group_nome); TextView tvComentario = convertView.findViewById(R.id.tv_group_comentario); tvNome.setText(parentComment.getNome()); tvComentario.setText(parentComment.getComentario()); return convertView; } // 渲染子项布局 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildComment childComment = (ChildComment) getChild(groupPosition, childPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.child_item, parent, false); } TextView tvNome = convertView.findViewById(R.id.tv_child_nome); TextView tvComentario = convertView.findViewById(R.id.tv_child_comentario); tvNome.setText(childComment.getNome()); tvComentario.setText(childComment.getComentario()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; // 如果需要子项可点击,就返回true } }
4. 编写父项和子项的布局文件
接下来创建两个布局文件,分别对应父项和子项的UI,把nome和comentario显示出来:
父项布局 res/layout/group_item.xml
<?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="vertical" android:padding="16dp"> <TextView android:id="@+id/tv_group_nome" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textStyle="bold"/> <TextView android:id="@+id/tv_group_comentario" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> </LinearLayout>
子项布局 res/layout/child_item.xml
<?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="vertical" android:padding="16dp" android:layout_marginLeft="24dp"> <!-- 子项缩进,视觉层级更清晰 --> <TextView android:id="@+id/tv_child_nome" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textStyle="italic"/> <TextView android:id="@+id/tv_child_comentario" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> </LinearLayout>
5. 在页面中配置ExpandableListView
最后一步,在你的Activity或Fragment里初始化ExpandableListView,把适配器设置进去:
public class MainActivity extends AppCompatActivity { private ExpandableListView mExpandableListView; private CustomExpandableListAdapter mAdapter; private List<ParentComment> mParentCommentList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mExpandableListView = findViewById(R.id.expandable_list); // 这里执行JSON解析,获取mParentCommentList(就是步骤2里的代码) String jsonString = "[ { \"nome\": \"Carlos\", \"comentario\": \"Esse dia foi show\", \"resp\": [ ] }, { \"nome\": \"Andre\", \"comentario\": \"Acho que não precisava disso\", \"resp\": [ { \"nome\": \"inutil\", \"comentario\": \"Sempre assim\" }, { \"nome\": \"Roberto\", \"comentario\": \"Se não estivessem fazendo nada errado,...\" } ] } ]"; Gson gson = new Gson(); Type listType = new TypeToken<List<ParentComment>>(){}.getType(); mParentCommentList = gson.fromJson(jsonString, listType); // 设置适配器 mAdapter = new CustomExpandableListAdapter(this, mParentCommentList); mExpandableListView.setAdapter(mAdapter); } }
这样就能完美实现你要的效果啦,父项和子项都能显示名称和评论字段~
内容的提问来源于stack exchange,提问作者user2950020
相关产品推荐
相关产品推荐

