问题描述:在完成了第一行代码的酷欧天气的手动刷新功能之后发现了如下问题。
刷新或者手动更换城市之后
天气预报出现了两次。下面上相关代码
private void showWeatherInfo(WeatherForecastBean weather){
String cityName = Utility.handleString(weather.getBasic().getLocation());
/*2019-04-10 13:55 只得到13:55 使用.split(" ")[1];*/
String updateTime = weather.getUpdate().getLoc().split(" ")[1];
String updateTime1 = updateTime.substring(0,updateTime.length()-1);
titleCity.setText(cityName);
titleUpdateTime.setText("更新时间:"+updateTime1);
forecastLayout.removeAllViews();
/* int k=0;
for(int i=0;i<forecastLayout.getChildCount();){
forecastLayout.removeViewAt(0);
k = forecastLayout.getChildCount();
}*/
Log.i("Count--","-1-"+forecastLayout.getChildCount());
for (DailyForecastBean dailyForecast :weather.getDaily_forecast()){
/*inflate()的作用就是将一个用xml定义的布局文件查找出来inflate(int resource, ViewGroup root, boolean attachToRoot)
* resource:需要加载布局文件的id,意思是需要将这个布局文件中加载到Activity中来操作
* root:需要附加到resource资源文件的根控件,
* 就是inflate()会返回一个View对象,如果第三个参数attachToRoot为true,
* 就将这个root作为根对象返回,
* 否则仅仅将这个root对象的LayoutParams属性附加到resource对象的根布局对象上,
* 也就是布局文件resource的最外层的View上,比如是一个LinearLayout或者其它的Layout对象*/
/*View是Android中所有控件的基类*/
View view = LayoutInflater.from(this).inflate(R.layout.forcast_item,forecastLayout,false);
TextView dataText = (TextView) view.findViewById(R.id.date_text);
TextView infoText = (TextView) view.findViewById(R.id.info_text);
TextView maxText = (TextView) view.findViewById(R.id.max_text);
TextView minText = (TextView) view.findViewById(R.id.min_text);
dataText.setText(Utility.handleString(dailyForecast.getDate()));
infoText.setText(Utility.handleString(dailyForecast.getCond_txt_d()));
maxText.setText(Utility.handleString(dailyForecast.getTmp_max())+" ℃");
minText.setText(Utility.handleString(dailyForecast.getTmp_min())+"℃ ~");
forecastLayout.addView(view);
}
Log.i("Count--","-2-"+forecastLayout.getChildCount());
weatherLayout.setVisibility(View.VISIBLE);
Toast.makeText(WeatherActivity.this,"刷新成功!",Toast.LENGTH_SHORT).show();
}
下面是控制台的输出:可以看到在forecastLayout.removeAllViews();之后的forecastLayout.getChildCount()的个数是0,第一次进入函数调用这个循环forecastLayout.getChildCount()是7个,也就是7天的预报
再看下拉刷新之后的控制台,循环之前确实已经remove了所有的子控件,但是循环出来子控件变成了14个,这或许就不该把目光放在forecastLayout.removeAllViews();上了,而是放在View上面,显然是增加了多个而不是没有移除之前的。
接着我们验证自己的猜想,改变Log的输出,观察控制台输出。
private void showWeatherInfo(WeatherForecastBean weather){
......
Log.i("Count--","1-->"+forecastLayout.getChildCount());
for (DailyForecastBean dailyForecast :weather.getDaily_forecast());
......
forecastLayout.addView(view);
Log.i("Count--","2-->"+forecastLayout.getChildCount());
}
Log.i("Count--","3-->"+forecastLayout.getChildCount());
weatherLayout.setVisibility(View.VISIBLE);
Toast.makeText(WeatherActivity.this,"刷新成功!",Toast.LENGTH_SHORT).show();
}
启动APP,不刷新第一遍没有问题
下拉刷新之后的控制台,走了十四次循环。
现在有充分的的理由怀疑是循环出了问题,这里的weather.getDaily_forecast()应该没有清空;调试一下!
for (DailyForecastBean dailyForecast :weather.getDaily_forecast()){
......
}
第一次进入是7个大小,刷新!果然变成了14,对象未清空!
在我的网络请求的对象解析中,把这个清空一下,问题解决!
public static WeatherForecastBean handleWeatherForecast(List<Forecast> list){
dailyForecastlist.clear();
Gson gson = new Gson();
for(int i = 0;i<7;i++){
DailyForecastBean dailyForecast = new DailyForecastBean();
dailyForecast.setCond_code_d(gson.toJson(list.get(0).getDaily_forecast().get(i).getCond_code_d()));/*白天天气状况代码*/
dailyForecast.setCond_code_n(gson.toJson(list.get(0).getDaily_forecast().get(i).getCond_code_n()));/*晚间天气状况代码*/
......
}