Retrofit2解析API返回JSON数组并适配Expandable List View问题
Retrofit2解析JSON后转可检索结构适配ExpandableListView方案
1. 确认数据模型类
先确保你的数据模型和API返回结构完全对应:
// 对应SUCCESS数组内的用户对象 public class User { @SerializedName("user_id") private String userId; // 若user_id是数字类型,改为int即可 @SerializedName("email") private String email; // Getter & Setter public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } // API返回的根模型 public class ApiResponse { @SerializedName("SUCCESS") private List<User> successList; public List<User> getSuccessList() { return successList; } public void setSuccessList(List<User> successList) { this.successList = successList; } }
2. 转成可通过user_id快速检索的结构
如果要高效通过user_id查找用户,用Map比数组更合适(数组检索需遍历,Map可实现O(1)查询)。若一定要用数组,也可以基于List转换:
// 假设已通过Retrofit回调拿到ApiResponse实例 ApiResponse response = ...; List<User> userList = response.getSuccessList(); // 转为Map:key=user_id,value=User对象 Map<String, User> userMap = new HashMap<>(); for (User user : userList) { userMap.put(user.getUserId(), user); } // 若需转为数组 User[] userArray = userList.toArray(new User[0]); // 数组检索方法(需遍历) public User findUserById(String targetId, User[] array) { for (User user : array) { if (targetId.equals(user.getUserId())) { return user; } } return null; }
3. 适配ExpandableListView
ExpandableListView需要分组数据和对应分组的子项数据,以下是通用实现步骤:
3.1 构建分组数据结构
这里以"按user_id首字母分组"为例,你可以根据需求调整分组规则:
Map<String, List<User>> groupData = new HashMap<>(); for (User user : userList) { // 取user_id首字母作为分组key String groupKey = user.getUserId().substring(0, 1).toUpperCase(); if (!groupData.containsKey(groupKey)) { groupData.put(groupKey, new ArrayList<>()); } groupData.get(groupKey).add(user); } // 提取分组标题的有序列表(ExpandableListView需要有序分组) List<String> groupTitles = new ArrayList<>(groupData.keySet()); // 可选:对分组标题排序 Collections.sort(groupTitles);
3.2 自定义ExpandableListAdapter
public class UserExpandableAdapter extends BaseExpandableListAdapter { private Context context; private List<String> groupTitles; private Map<String, List<User>> groupUserMap; public UserExpandableAdapter(Context context, List<String> groupTitles, Map<String, List<User>> groupUserMap) { this.context = context; this.groupTitles = groupTitles; this.groupUserMap = groupUserMap; } @Override public int getGroupCount() { return groupTitles.size(); } @Override public int getChildrenCount(int groupPosition) { return groupUserMap.get(groupTitles.get(groupPosition)).size(); } @Override public Object getGroup(int groupPosition) { return groupTitles.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return groupUserMap.get(groupTitles.get(groupPosition)).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) { if (convertView == null) { convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_expandable_list_item_1, parent, false); } ((TextView) convertView.findViewById(android.R.id.text1)).setText(groupTitles.get(groupPosition)); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_2, parent, false); } User user = (User) getChild(groupPosition, childPosition); TextView userIdTv = convertView.findViewById(android.R.id.text1); TextView emailTv = convertView.findViewById(android.R.id.text2); userIdTv.setText("用户ID: " + user.getUserId()); emailTv.setText("邮箱: " + user.getEmail()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }
3.3 绑定适配器到ListView
ExpandableListView expandableListView = findViewById(R.id.your_expandable_list_id); UserExpandableAdapter adapter = new UserExpandableAdapter(this, groupTitles, groupData); expandableListView.setAdapter(adapter);
补充说明
- 若不需要分组,可将所有用户放入一个默认分组(比如"全部用户"),直接使用
groupData.put("全部用户", userList)即可。 - 确保Retrofit已配置Gson转换器(添加依赖
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'),否则无法自动解析JSON到模型类。
内容的提问来源于stack exchange,提问作者Hiraeths
相关产品推荐
相关产品推荐

