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

点击图片按钮无法分别获取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;

额外建议

  1. 所有空对象都要加非空判断,避免空指针崩溃;
  2. 错误回调里一定要加提示,方便调试定位问题;
  3. 不要依赖数组索引去取元素(比如直接取actionButtons[0]),如果后端返回的顺序变化,代码会直接失效,通过type匹配更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:14:48