使用AutoCompleteTextView+JSON遇遍历错误:foreach不适用于Result类型
解决“foreach不适用于com.example.program.model.Result类型”的问题
嘿,我一眼就看出问题出在哪了——你的Example类里的result字段是单个Result对象,但你在代码里却把它当成了**列表(List)**来遍历,这就导致foreach循环直接报错啦。
错误根源分析
先看你的Example类定义:
public class Example { @SerializedName("result") @Expose private Result result; // 这里是单个Result对象,不是List<Result>集合 // ... getter和setter方法 }
而你在DownloadGames方法里写了这段代码:
for(Result result: ((Example) response.body()).getResult()){ ... }
getResult()返回的是单个Result对象,可foreach循环只能用于实现Iterable接口的集合(比如List、Set),所以编译器直接抛出“foreach不适用于Result类型”的错误。
两种解决方案(根据你的API返回结构选择)
方案一:如果API返回的是单个Result对象
如果你的接口返回的JSON确实是单个Result结构(比如{"result": {"title": "GTA"}}),那你根本不需要循环,直接获取单个对象的title即可:
@Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { alertDialog.dismiss(); if (response.body() != null) { Example example = (Example) response.body(); List<String> strings= new ArrayList<String>(); // 直接获取单个Result的title添加到列表 strings.add(example.getResult().getTitle()); ArrayAdapter<String> adapteo = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_dropdown_item_1line, strings); storeTV.setAdapter(adapteo); // 注意:如果要显示releaseDate,需要先给Result类补充对应字段和getter // contentTitle.setText(example.getResult().getReleaseDate()); ... } } }
同时记得给Result类补充releaseDate字段(如果API返回该字段的话):
public class Result { @SerializedName("title") @Expose private String title; @SerializedName("releaseDate") // 要和JSON里的字段名完全对应 @Expose private String releaseDate; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getReleaseDate() { return releaseDate; } public void setReleaseDate(String releaseDate) { this.releaseDate = releaseDate; } }
方案二:如果API返回的是Result列表(更适配AutoCompleteTextView场景)
如果你的接口实际返回的是多个Result的集合(比如{"result": [{"title": "GTA"}, {"title": "COD"}]}),那你需要修改Example类的result字段为列表类型:
public class Example { @SerializedName("result") @Expose private List<Result> result; // 把单个Result改成List<Result> public List<Result> getResult() { return result; } public void setResult(List<Result> result) { this.result = result; } }
这样你的foreach循环就能正常工作了,同时调整releaseDate的获取逻辑(因为现在是列表,你可能需要取第一个元素或者批量处理):
@Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { alertDialog.dismiss(); if (response.body() != null) { Example example = (Example) response.body(); List<String> strings= new ArrayList<String>(); // 现在foreach可以正常遍历List<Result>了 for(Result result: example.getResult()){ strings.add(result.getTitle()); } ArrayAdapter<String> adapteo = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_dropdown_item_1line, strings); storeTV.setAdapter(adapteo); // 显示第一个结果的releaseDate(记得先判断列表非空) if(!example.getResult().isEmpty()){ contentTitle.setText(example.getResult().get(0).getReleaseDate()); } ... } } }
额外小提示
- 建议使用泛型Call,避免强制类型转换,比如把
Call call = gamesInterface.getGamesbyName(...)改成Call<Example> call = gamesInterface.getGamesbyName(...),这样response.body()直接就是Example类型,不用强转,更安全。 - 一定要核对API返回的JSON结构和你的Model类字段是否完全对应,这是Retrofit解析时最容易踩的坑。
内容的提问来源于stack exchange,提问作者VKORK
相关产品推荐
相关产品推荐

