点击图片按钮无法分别获取JSON数组对应对象的问题求助
问题分析与解决方案
你遇到的问题核心非常清晰——解析后端返回的数组时,循环覆盖了单个变量的值,导致最终只保留了数组最后一个元素(Light类型)的数据,所以点击第一个按钮(对应Strobe类型)时,getType已经被替换成"Light",判断条件永远不成立,自然无法触发对应的请求。
问题根源拆解
看你的解析代码,你用for (ActionButton actionButton1 : actionButton)遍历数组,但每次循环都把getOnUrl、getOffUrl、getType、message这些变量重新赋值。循环结束后,这些变量只会保留最后一个元素的信息,也就是数组里第二个Light类型对象的数据。这直接导致第一个按钮的if (getType.equals("Strobe"))条件永远为false,根本走不进对应的请求逻辑。
方案一:用Map存储不同类型的按钮数据
推荐用Map<String, ActionButton>按type存储每个按钮的完整数据,后续点击按钮时可以直接根据类型取出对应的对象,这种方式扩展性更强,就算后续新增其他类型按钮也能兼容。
修改解析数据代码
// 先定义类成员变量存储Map private Map<String, ActionButton> actionButtonMap = new HashMap<>(); // 解析部分修改 final String potentialId = SitesUtil.getInstance().getSelectedPotentialId(); String urlOne = UrlUtility.getActionUrl(potentialId, cameraId); RequestQueue requestQueue = Volley.newRequestQueue(getContext()); final StringRequest stringRequest = new StringRequest(Request.Method.GET, urlOne, new Response.Listener<String>() { @Override public void onResponse(String response) { Gson gson = new Gson(); ActionButton[] actionButtons = gson.fromJson(response, ActionButton[].class); // 遍历数组,按type存入Map for (ActionButton btn : actionButtons) { actionButtonMap.put(btn.getType(), btn); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // 增加错误提示,方便调试 Toast.makeText(getContext(), "按钮数据加载失败", Toast.LENGTH_SHORT).show(); } }); requestQueue.add(stringRequest);
修改点击事件代码
@Override public void onClick(View v) { switch (v.getId()) { case R.id.imageButton: // 取出Strobe类型的按钮对象 ActionButton strobeBtn = actionButtonMap.get("Strobe"); if (strobeBtn != null) { RequestQueue requestQueue = Volley.newRequestQueue(getContext()); StringRequest stringRequest = new StringRequest(Request.Method.GET, strobeBtn.getOnUrl(), new Response.Listener<String>() { @Override public void onResponse(String response) { Toast.makeText(getContext(), strobeBtn.getOnSuccessMessage(), Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getContext(), "Strobe请求失败", Toast.LENGTH_SHORT).show(); } }); requestQueue.add(stringRequest); } break; case R.id.imageButton2: // 取出Light类型的按钮对象 ActionButton lightBtn = actionButtonMap.get("Light"); if (lightBtn != null) { RequestQueue requestQueue = Volley.newRequestQueue(getContext()); StringRequest stringRequest = new StringRequest(Request.Method.GET, lightBtn.getOnUrl(), new Response.Listener<String>() { @Override public void onResponse(String response) { Toast.makeText(getContext(), lightBtn.getOnSuccessMessage(), Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getContext(), "Light请求失败", Toast.LENGTH_SHORT).show(); } }); requestQueue.add(stringRequest); } break; } }
方案二:直接存储两个单独变量(如果确定只有两种类型)
如果后端返回的数组固定只有Strobe和Light两个元素,也可以直接定义两个类成员变量分别存储,逻辑更简单:
定义成员变量
private ActionButton strobeButton; private ActionButton lightButton;
修改解析代码
@Override public void onResponse(String response) { Gson gson = new Gson(); ActionButton[] actionButtons = gson.fromJson(response, ActionButton[].class); for (ActionButton btn : actionButtons) { if ("Strobe".equals(btn.getType())) { strobeButton = btn; } else if ("Light".equals(btn.getType())) { lightButton = btn; } } }
修改点击事件
case R.id.imageButton: if (strobeButton != null) { // 直接使用strobeButton的属性发起请求 RequestQueue requestQueue = Volley.newRequestQueue(getContext()); StringRequest stringRequest = new StringRequest(Request.Method.GET, strobeButton.getOnUrl(), new Response.Listener<String>() { @Override public void onResponse(String response) { Toast.makeText(getContext(), strobeButton.getOnSuccessMessage(), Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getContext(), "请求失败", Toast.LENGTH_SHORT).show(); } }); requestQueue.add(stringRequest); } break; case R.id.imageButton2: if (lightButton != null) { // 直接使用lightButton的属性发起请求 // 代码逻辑同上 } break;
额外建议
- 所有空对象都要加非空判断,避免空指针崩溃;
- 错误回调里一定要加提示,方便调试定位问题;
- 不要依赖数组索引去取元素(比如直接取
actionButtons[0]),如果后端返回的顺序变化,代码会直接失效,通过type匹配更可靠。
内容的提问来源于stack exchange,提问作者7
相关产品推荐
相关产品推荐

