从AsyncTask内部刷新ListView的适配器,无需重复

时间:2013-11-23 20:17:25

标签: android eclipse listview android-asynctask

我有一个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.
        }
    });

AsyncTask(我删除了一些不必要的代码)

    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);
        }
    }

ScheduleEventAdapter

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(),但它不起作用。

我能想到的唯一解决方案是比较数组中每个对象的每个字段,但这听起来就像是对我的性能打击。

如果是这样,解决此问题的最有效和最正确的方法是什么?

0 个答案:

没有答案