这可能是一个noob问题,但我对于所有这些sqlite数据库 – 游标适配器 – ListView-Do-It-Properly-Stuff来说都是新的.
我拥有的:
在我的MainActivity我有一个ListView.我使用sqlite数据库,并使用扩展SimpleCursorAdapter的自定义适配器填充ListView.通过单击我的ActionBar中的项目,我激活上下文动作模式.一切工作到目前为止.
我想要的是:
通过点击ListView项目中的某个图标,应该删除相应的数据库行,并且应该刷新ListView.
我的问题:
如何正确刷新我的光标和我的ListView?当我不在我的OnClickListener中使用cursor.requery()并且使用cursor = dbm.getIOIOSensorsCursor()而不是在行下面的几行CursorIndexOutOfBoundsException
int state = cursor.getInt(cursor.getColumnIndex(IOIOSensorSchema.STATE));
我的应用程序崩溃,但重新加载后,数据库已被删除,并且相应的ListView项目已经消失.
我猜,在get get方法中,崩溃必须与_position有关,因为_position是final.但是,当我使用cursor.requery()一切都可以正常工作.
但是这种方法已被弃用,文档说“不要使用…”.我是一个正确编码的朋友(我还是一个初学者,想要学习编码正确的方式,而不是快速而脏),并想知道如何做到这一点.我不知道这是否重要,但我只是在我的(真正快速的)Nexus 4上测试我的应用程序.似乎没有任何问题刷新光标足够快,但我不知道它是否可以在较慢的设备上工作.万一重要的是,我的数据库将包含大约10-20行和大约12列.我想这是一个非常小的数据库.
public class IOIOSensorCursorAdapterCam extends SimpleCursorAdapter { static class ViewHolder { ImageView stateIV,removeIV; TextView nameTV,pinNumberTV,FeedIDTV,freqTV; } private Context ctx; private Cursor cursor; private IodDatabaseManager dbm; public IOIOSensorCursorAdapterCam(Context _context,int _layout,Cursor _cursor,String[] _from,int[] _to,int _flags) { super(_context,_layout,_cursor,_from,_to,_flags); ctx = _context; cursor = _cursor; dbm = new IodDatabaseManager(_context); } @Override public View getView(final int _position,View _convertView,ViewGroup _parent) { ViewHolder holder = null; LayoutInflater inflater = (LayoutInflater) ctx .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // There is no view at this position,we create a new one. In this case // by inflating an xml layout. if (_convertView == null) { // Inflate a layout _convertView = inflater.inflate(R.layout.listview_item_sensor_cam,null); holder = new ViewHolder(); holder.stateIV = (ImageView) _convertView .findViewById(R.id.stateImageView); holder.nameTV = (TextView) _convertView .findViewById(R.id.sensorNameTextView); holder.pinNumberTV = (TextView) _convertView .findViewById(R.id.sensorPinNumberTextView); holder.FeedIDTV = (TextView) _convertView .findViewById(R.id.sensorFeedIDTextView); holder.freqTV = (TextView) _convertView .findViewById(R.id.sensorFrequencyTextView); holder.removeIV = (ImageView) _convertView .findViewById(R.id.removeImageView); _convertView.setTag(holder); } // We recycle a View that already exists. else { holder = (ViewHolder) _convertView.getTag(); } // Set an OnClickListener to the "Delete Icon" holder.removeIV.setOnClickListener(new OnClickListener() { @SuppressWarnings("deprecation") @Override public void onClick(View _view) { cursor.moveToPosition(_position); // Delete sensor from database here int sensorID = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.SENSOR_ID)); dbm.deleteIOIOSensor(sensorID); // This leads to a "CursorIndexOutOfBoundsException" and cannot // be used to refresh the ListView // cursor = dbm.getIOIOSensorsCursor(); // Refresh ListView cursor.requery(); notifyDataSetChanged(); } }); cursor.moveToPosition(_position); if (cursor.getCount() > 0) { int state = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.STATE)); if (state == 0) { holder.stateIV.setImageResource(R.drawable.av_play_over_video); holder.stateIV.setColorFilter(ctx.getResources().getColor( R.color.hint_lighter_gray)); // _convertView.setAlpha((float) 0.5); holder.nameTV.setTextColor(ctx.getResources().getColor( R.color.hint_darker_gray)); } else { holder.stateIV.setImageResource(R.drawable.av_pause_over_video); holder.stateIV.setColorFilter(ctx.getResources().getColor( android.R.color.holo_green_light)); // _convertView.setAlpha((float) 1); holder.nameTV.setTextColor(ctx.getResources().getColor( android.R.color.black)); } // Set the sensor's name to the according TextView String sensorName = cursor.getString(cursor .getColumnIndex(IOIOSensorSchema.NAME)); holder.nameTV.setText(sensorName); // Set the sensor's pin number to the according TextView int pinNumber = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.PIN_NUMBER)); holder.pinNumberTV.setText("" + pinNumber); // Set the sensor's Feed ID to the according TextView int FeedID = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.Feed_ID)); holder.FeedIDTV.setText("" + FeedID); // Set the sensor's frequency to the according TextView int frequency = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.FREQUENCY)); int timeUnit = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.TIME_UNIT)); String frequencyTextViewText = ""; switch (timeUnit) { case IodioIOSensor.TIME_UNIT_MINUTES: frequencyTextViewText = frequency + " min"; break; case IodioIOSensor.TIME_UNIT_HOURS: frequencyTextViewText = frequency + " h"; break; default: frequencyTextViewText = frequency + " sec"; break; } holder.freqTV.setText(frequencyTextViewText); } return _convertView; } }
编辑:
在实现解决方案之后,这是OnCickListener的相关代码:
// Set an OnClickListener to the "Delete Icon" holder.removeIV.setOnClickListener(new OnClickListener() { @Override public void onClick(View _view) { cursor.moveToPosition(_position); // Delete sensor from database here int sensorID = cursor.getInt(cursor .getColumnIndex(IOIOSensorSchema.SENSOR_ID)); dbm.deleteIOIOSensor(sensorID); Toast.makeText(ctx,R.string.toast_sensor_deleted,Toast.LENGTH_SHORT).show(); // Refresh ListView cursor = dbm.getIOIOSensorsCursor(); swapCursor(cursor); notifyDataSetChanged(); } });