Android开发:ArrayList数据被覆盖,RecyclerView仅显天气API最后一项
解决RecyclerView仅显示最后一条天气数据的问题
问题场景
从天气API获取包含日期时间数组、温度、风速等信息的JSON数据,尝试构建Condition列表关联天气状况与对应时间,期望RecyclerView展示所有时段的天气数据,但目前仅能显示列表的最后一个元素。
错误原因
问题出在WeatherActivity的循环逻辑中:
- 每次循环都会新建
ArrayList<Condition>,导致之前添加的数据被丢弃 - 每次循环都重新初始化RecyclerView的适配器并设置给RecyclerView,最终只有最后一次循环的单元素列表被展示
修复方案
将ArrayList<Condition>的初始化移到循环外部,循环内仅向列表添加Condition对象;待所有数据解析完成后,再在UI线程中配置RecyclerView并设置适配器。同时修复代码中其他潜在问题(如switch分支漏写break)。
修改后的WeatherActivity代码
public class WeatherActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_weather); int District = getIntent().getIntExtra("District", -1); String latitude = ""; String longitude = ""; switch (District) { case 0: latitude = "55.753600"; longitude = "37.621184"; break; case 1: latitude = "55.838390"; longitude = "37.525774"; break; case 2: latitude = "55.854875"; longitude = "37.632565"; break; case 3: latitude = "55.787715"; longitude = "37.775631"; break; case 4: latitude = "55.692019"; longitude = "37.754592"; break; case 5: latitude = "55.622014"; longitude = "37.678065"; break; case 6: latitude = "55.662735"; longitude = "37.576187"; break; // 修复漏写的break case 7: latitude = "55.778003"; longitude = "37.443533"; break; case 8: latitude = "55.829370"; longitude = "37.451555"; break; case 9: latitude = "55.987583"; longitude = "37.194250"; break; case 10: latitude = "55.355802"; longitude = "37.146999"; break; case 11: latitude = "55.594351"; longitude = "37.371452"; break; default: break; } String address = "https://api.open-meteo.com/v1/forecast?latitude=" + latitude + "&longitude=" + longitude + "&hourly=temperature_2m,relative_humidity_2m,apparent_temperature,precipitation_probability,snowfall,cloud_cover,wind_speed_10m&wind_speed_unit=ms&timezone=Europe%2FMoscow&forecast_days=1"; new Thread(() -> { try { URL url = new URL(address); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); InputStream stream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); StringBuilder buffer = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { buffer.append(line).append("\n"); } String result = buffer.toString(); if (reader != null) { try { JSONObject object = new JSONObject(result); JSONArray timeArray = object.getJSONObject("hourly").getJSONArray("time"); JSONArray temperatureArray = object.getJSONObject("hourly").getJSONArray("temperature_2m"); JSONArray humidityArray = object.getJSONObject("hourly").getJSONArray("relative_humidity_2m"); JSONArray precipitationArray = object.getJSONObject("hourly").getJSONArray("precipitation_probability"); JSONArray cloudArray = object.getJSONObject("hourly").getJSONArray("cloud_cover"); JSONArray windSpeedArray = object.getJSONObject("hourly").getJSONArray("wind_speed_10m"); JSONArray snowArray = object.getJSONObject("hourly").getJSONArray("snowfall"); // 将列表初始化移到循环外部 ArrayList<Condition> conditions = new ArrayList<>(); // 提前初始化日期格式化对象,避免重复创建 SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm"); SimpleDateFormat outputFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); for (int i = 0; i < timeArray.length(); i++) { String time = timeArray.getString(i); Date date = null; try { date = inputFormat.parse(time); } catch (ParseException e) { e.printStackTrace(); } String outputString = outputFormat.format(date); String temperature = temperatureArray.getString(i); String humidity = humidityArray.getString(i); double precipitation = precipitationArray.getDouble(i); double cloud = cloudArray.getDouble(i); String windSpeed = windSpeedArray.getString(i); String snowfall = snowArray.getString(i); // 仅向已有列表添加元素 conditions.add(new Condition(outputString, temperature, humidity, precipitation, cloud, windSpeed, snowfall)); } // 循环结束后,统一在UI线程配置RecyclerView runOnUiThread(() -> { RecyclerView rcView = findViewById(R.id.recyclerView2); // 仅设置一次LayoutManager(如果布局中没设置的话) if (rcView.getLayoutManager() == null) { rcView.setLayoutManager(new LinearLayoutManager(WeatherActivity.this, LinearLayoutManager.VERTICAL, false)); } WeatherAdapter adapter = new WeatherAdapter(conditions); rcView.setAdapter(adapter); }); } catch (JSONException e) { e.printStackTrace(); } } connection.disconnect(); } catch (IOException e) { e.printStackTrace(); } }).start(); } }
额外优化建议
- 线程安全问题:
SimpleDateFormat不是线程安全的,建议使用Java 8+的DateTimeFormatter替代,或者将格式化对象放在循环内(但会增加对象创建开销)。 - 网络请求优化:建议使用Retrofit、OkHttp等成熟的网络库替代原生
HttpURLConnection,简化网络请求代码并提升稳定性。 - RecyclerView性能:可以给
WeatherAdapter添加数据更新方法,避免每次都创建新的适配器实例。
内容的提问来源于stack exchange,提问作者user25407839
相关产品推荐
相关产品推荐

