我有一个ListView
,显然是一个使用List<T>
对象的适配器
我添加了一个应该刷新listview的按钮(=重新查询数据库并重新创建ListView
)。
以上所有内容(从查询数据库到设置适配器)都发生在AsyncTask
内。
mRefreshButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setClickable(false);
new GetScheduleTask().execute((Void[]) null); //Basically, execute it again.
}
});
private class GetScheduleTask extends AsyncTask<Void, Void, List<Object[]>> {
@Override
protected List<Object[]> doInBackground(Void... params) {
SQLiteDatabase db = SchooLauncherDbHelper.getInstance(getActivity()).getReadableDatabase();
//TODO test repetition
String sql = "LONG A** SQL HERE";
Cursor c = db.rawQuery(sql, new String[] {String.valueOf(cal.getTimeInMillis()), String.valueOf(cal.getTimeInMillis()),
String.valueOf(cal.getTimeInMillis()), String.valueOf(cal.get(Calendar.MONTH))});
while(c.moveToNext()) {
......................
mEventList.add(new Object[] {new Class(...), new Subject(...)});
}
}
db.close();
return mEventList;
}
@Override
protected void onPostExecute(List<Object[]> result) {
mScheduleListView = (ListView) view
.findViewById(R.id.mScheduleListView);
TextView myTv = new TextView(getActivity());
myTv.setText("No Results");
mScheduleListView.setEmptyView(myTv);
mScheduleEventAdapter = new ScheduleEventAdapter(getActivity(),
R.layout.schedule_item_layout, mEventList);
mScheduleListView.setAdapter(mScheduleEventAdapter);
if(!mImageView.isClickable())
mImageView.setClickable(true);
}
}
public class ScheduleEventAdapter extends ArrayAdapter<Object[]>{
private Context context;
private int layoutResourceId;
private List<Object[]> data = null;
private View row = null;
private LayoutInflater inflater;
private Subject mSubject;
private Event mEvent;
private String mEventStartTime, mEventEndTime;
public ScheduleEventAdapter(Context context, int layoutResourceId, List<Object[]> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if(row == null) {
inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(this.layoutResourceId, parent, false);
}
mSubject = (Subject) data.get(position)[1];
mEvent = (Event) data.get(position)[0];
((ImageView) row.findViewById(R.id.subjecticon)).setImageResource(mSubject.icon);
((TextView) row.findViewById(R.id.schedule_event_subject_name)).setText(mSubject.name);
((TextView) row.findViewById(R.id.schedule_event_title)).setText(mEvent.mEventTitle);
((TextView) row.findViewById(R.id.schedule_event_location)).setText(((Class)mEvent).mClassLocation);
this.mEventStartTime = ((int) mEvent.mEventStartTime / (1000*60*60)) + ":" + ((int) (((mEvent.mEventStartTime / (1000*60)) % 60)));
this.mEventEndTime = ((int) mEvent.mEventEndTime / (1000*60*60)) + ":" + ((int) (((mEvent.mEventEndTime / (1000*60)) % 60)));
((TextView) row.findViewById(R.id.schedule_event_time)).setText(this.mEventStartTime + " - " + this.mEventEndTime);
return row;
}
}
问题是该按钮有效,但不是重新创建列表,而是显示重复项。
正如您所看到的,正在添加新项目mEventList
,甚至已经显示的项目。
我可以使用if
语句和列表的.contains()
方法来确定是否需要将对象添加到列表中,但问题是,即使内容的对象可能是相同的,指针是不同的,我猜是为什么它也不起作用(我试过)。
我也尝试重置适配器并使用数据和.notifyDataSetChanged()
,但它不起作用。
我能想到的唯一解决方案是比较数组中每个对象的每个字段,但这听起来就像是对我的性能打击。
如果是这样,解决此问题的最有效和最正确的方法是什么?