Android嵌套JSON解析、ListView多级展示及Fragment筛选问题求助
解决Android中多级JSON解析与按状态分Fragment展示的问题
我来帮你搞定这两个核心需求:解析多级嵌套的name字段填充到ListView的三个TextView,以及按is_broken/is_repaired/is_ok状态分Fragment展示数据。下面是具体的实现步骤和代码修改:
一、解析多级嵌套的JSON数据
你的JSON结构里每个data项都有多层asset_parent嵌套,我们需要逐层提取这些嵌套的name,对应到textCucu(最底层)、textAnak(中间层)、textBapak(最顶层)。
修改AsyncTask中的解析逻辑
在daftarAset的doInBackground方法里,替换原有的解析代码,增加多级嵌套的处理:
try { str_json = json.getJSONArray("data"); for (int i = 0; i < str_json.length(); i++) { JSONObject ar = str_json.getJSONObject(i); // 提取各级name,默认空字符串避免空指针 String cucuName = ar.getString("name").trim(); // 最底层(如Table) String anakName = ""; String bapakName = ""; // 解析第一层asset_parent if (ar.has("asset_parent") && !ar.isNull("asset_parent")) { JSONObject parent1 = ar.getJSONObject("asset_parent"); anakName = parent1.getString("name").trim(); // 中间层(如2nd Floor) // 解析第二层asset_parent if (parent1.has("asset_parent") && !parent1.isNull("asset_parent")) { JSONObject parent2 = parent1.getJSONObject("asset_parent"); bapakName = parent2.getString("name").trim(); // 最顶层(如Grubi Building) } } // 把三个name存入HashMap,同时保存状态字段用于筛选 HashMap<String, String> map = new HashMap<>(); map.put(BaikFragment.in_aset, cucuName); map.put(BaikFragment.in_ruang, anakName); map.put(BaikFragment.in_gedung, bapakName); map.put("is_broken", String.valueOf(ar.getBoolean("is_broken"))); map.put("is_repaired", String.valueOf(ar.getBoolean("is_repaired"))); map.put("is_ok", String.valueOf(ar.getBoolean("is_ok"))); data_map.add(map); } } catch (JSONException e) { e.printStackTrace(); }
修改Adapter的getView方法
现在Adapter可以拿到三个层级的name,直接填充到对应的TextView:
@Override public View getView(int position, View convertView, ViewGroup parent) { View vi = convertView; if (convertView == null) vi = inflater.inflate(R.layout.list_chart, null); TextView textCucu = (TextView) vi.findViewById(R.id.aset1); TextView textAnak = (TextView) vi.findViewById(R.id.lokasi); TextView textBapak = (TextView) vi.findViewById(R.id.waktu); HashMap<String, String> getdata = data.get(position); textCucu.setText(getdata.get(BaikFragment.in_aset)); // 最底层name textAnak.setText(getdata.get(BaikFragment.in_ruang)); // 中间层name textBapak.setText(getdata.get(BaikFragment.in_gedung)); // 最顶层name return vi; }
二、按状态分Fragment展示数据
你需要三个Fragment分别对应不同状态,每个Fragment只加载符合自身状态的数据,具体实现如下:
1. 给每个Fragment添加状态标识
以你的BaikFragment(对应is_ok=true)为例,添加筛选常量:
// 当前Fragment的筛选状态标识 private static final String FILTER_STATUS = "is_ok";
2. 修改AsyncTask,筛选对应状态的数据
解析完所有数据后,根据当前Fragment的状态过滤出符合条件的条目,再更新UI:
// 筛选符合当前Fragment状态的数据 ArrayList<HashMap<String, String>> filteredData = new ArrayList<>(); for (HashMap<String, String> item : data_map) { boolean isMatch = Boolean.parseBoolean(item.get(FILTER_STATUS)); if (isMatch) { filteredData.add(item); } } // 在UI线程更新ListView getActivity().runOnUiThread(new Runnable() { @Override public void run() { list = (ListView) getView().findViewById(R.id.baik_list); adapter = new AssetsAdapter(getActivity(), filteredData); list.setAdapter(adapter); setListViewHeightBasedOnChildren(list); } });
3. 复制模板创建另外两个Fragment
- BrokenFragment:将
FILTER_STATUS设为"is_broken",使用对应的布局文件(如fragment_broken.xml,结构和fragment_baik.xml一致) - RepairedFragment:将
FILTER_STATUS设为"is_repaired",使用对应的布局文件(如fragment_repaired.xml)
这样每个Fragment只会展示符合自身状态的数据。
额外优化建议
- 建议用POJO实体类代替HashMap存储数据,比如创建
Asset类包含各级name和状态字段,解析JSON时直接映射为对象,代码会更易读、易维护。 - 避免在
doInBackground中调用runOnUiThread,可以把解析好的数据传递到onPostExecute方法中再更新UI,更符合AsyncTask的设计规范。
内容的提问来源于stack exchange,提问作者Mo Ne
相关产品推荐
相关产品推荐

