前言:ListView和RecyclerView基本用法很简单,即三要素:控件(界面),数据源,适配器。但基本控件无法满足需求只能定制时,遇到一些问题,总结一下。
- 性能优化
- 滑动时数据加载混乱
- nofityDataSetChanged不起作用
性能优化
性能优化,大多是在getView()方法中采用内部类ViewHolder,保存已经加载过的布局convertView和控件实例如TextView、ImageView等。滑动时会实时加载getView(),其中获得布局和控件实例的inflate和findViewById方法比较耗时,如果有现成的convertView和TextView、ImageView等可以复用,会提高运行效率,在快速滑动时表现出更好的性能。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
SensorItemInfo sensorItemInfo = (SensorItemInfo)getItem(position);
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.sensor_task_info_item, null);
holder.sensortype = (TextView) convertView.findViewById(R.id.sensortype);
holder.average_value = (TextView) convertView.findViewById(R.id.average_value);
holder.day_thre = (TextView) convertView.findViewById(R.id.day_threshold);
holder.night_thre = (TextView) convertView.findViewById(R.id.night_threshold);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag(); //复用convertView
}
int sensorType = sensorItemInfo.getSensorType();
String unit = UIDisplay.showSensInforListUnit(sensorType); //根据类型获取单位
holder.sensortype.setText("类型:" + UIDisplay.showSensInfoListSensType(sensorItemInfo.getSensorType())); //根据int值获取传感器类型
holder.average_value.setText("平均值:" + UIDisplay.showSensInfoListValue(sensorType, sensorItemInfo.getAverageValue()) + unit);
holder.day_thre.setText("白天门限:" + UIDisplay.showSensInfoListValue(sensorType, sensorItemInfo.getAverageValue()) + unit);
holder.night_thre.setText("夜间门限:" + UIDisplay.showSensInfoListValue(sensorType, sensorItemInfo.getAverageValue()) + unit);
return convertView;
}
滑动时数据加载错乱
数据加载混乱有很多解决方法,目前学习的,是通过setTag()解决。通过setTag(),关联view和控件,控件和数据,这里的itemInfo,可以是check状态,也可以是ImageView的url。
- convertView.setTag(viewHolder)
- viewHolder.***.setTag(itemInfo)
我遇到的问题是,全部设置成联动模式时,左右滑动,不同设备上绑定的传感器个数和种类就会诡异地变来变去。数据不是简单状态值或是某张图片的url,是一个保存了传感器类型和数值的List<\E>。setTag()的方法我没有尝试,目前的解决方法是在横向滑动的RecyclerView中,选择 viewHolder.setIsRecyclable(false);
禁止复用。
notifyDataSetChanged不起作用
adapter.notifyDatasetChanged()不起作用,参考资料[1]中作者总结了三种原因,关键问题都出在数据源。数据的更新和引用必须是同一个,数据源更新也需要通知adapter。
横向RecyclerView和竖向ListView的混合展示
RecyclerView禁止复用,ListView进行优化,滑动时没有卡顿,但是根据传感器实时值自动刷新界面功能还没有实现。
[1]. ListView和GridView调用nofityDataSetChanged界面不刷新 [2]. ListView优化机制及滑动数据时出现的数据混乱错误问题