删除列表项,然后查询数据库会引发异常

时间:2013-03-30 04:23:09

标签: android database android-arrayadapter listactivity

我已经将列表项目从BaseAdapter转换为ArrayAdapter ListActivity,因为我在另一个问题中被告知ArrayAdapter更具动态性和更好,特别是允许从列表中删除项目然后更新到反映这种删除。我仍在使用ArrayAdapter遇到同样的问题,如下所示:

我得到了我的列表数据:

public void loadAdapter(){

    DatabaseHelper helper = new DatabaseHelper(ActivityMain.this);
    database = helper.getReadableDatabase();

    Cursor data = database.query("list_data", fields, null, null, null,
            null, null);
    Integer tindex = data.getColumnIndex("listTitle");
    Integer iindex = data.getColumnIndex("listType");

    itemCount = 0;
    for (data.moveToFirst(); !data.isAfterLast(); data.moveToNext()) {
        m_parts.add(new Item(data.getString(tindex), data.getString(iindex)));
        itemCount++;
    }

    data.close();

    for (int j = 0; j < 10; j++) {
        m_parts.add(new Item("", "R"));
    }

    m_adapter = new ItemAdapter(ActivityMain.this, R.layout.listview, m_parts);

    setListAdapter(m_adapter);  
}

使用此自定义适配器:

public class ItemAdapter extends ArrayAdapter<Item> {

    private ArrayList<Item> objects;

    public ItemAdapter(Context context, int textViewResourceId,
            ArrayList<Item> objects) {
        super(context, textViewResourceId, objects);
        this.objects = objects;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;

        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.listview, null);
        }

        Item i = objects.get(position);

        if (i != null) {

            TextView textview = (TextView) v.findViewById(R.id.tv_main);
            ImageView imageview = (ImageView) v.findViewById(R.id.iv_main);
            TextView textview2 = (TextView) v.findViewById(R.id.tv_main2);
            textview.setText(i.getText());
            textview2.setText(i.getText());

            imageview.setScaleType(ScaleType.FIT_XY);
            Integer theDrawable;
            if (i.getImage() != "L") {
                theDrawable = R.drawable.listview_regular;
            } else {
                theDrawable = R.drawable.listview_location;
            }
            imageview.setImageResource(theDrawable);

        }

        v.setOnClickListener(new OnItemClickListener(position));
        v.setOnLongClickListener(new OnItemLongClickListener(position));
        return v;

    }
}

longclicklistener的上下文菜单提供了一个删除选项,它使用了这个

private void showDialogOnLongClick(final int position) {

 Builder alert = new AlertDialog.Builder(this);

 ArrayList<String> listInfo = getListInfo(position);
 String content = listInfo.get(1);
 String numItems = "";

 if (content != null && content.indexOf("|~|") > -1) {
 String[] contentSplit = content.split("\\|\\~\\|");
 numItems = contentSplit.length + " items in list";
 } else {
 numItems = "No items in list";
 }

 String listTitle = listInfo.get(0);
 String created = "Created: " + listInfo.get(2);
 String modified = "Modified: " + listInfo.get(3);
 String delete = "Delete";
 String edit = "Edit";
 final String[] items = new String[] { created, modified, numItems,
 delete, edit };

 alert.setTitle(listTitle);

 alert.setItems(items, new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 switch (which) {

 case 3:
 if (deleteList(position)) {
//listview.invalidate();
//Item itemToRemove = m_parts.remove(position);
//m_adapter.remove(itemToRemove);
//m_adapter.remove(toRemove);
//m_adapter.notifyDataSetInvalidated();     <-- These are all things I've tried
//m_adapter.clear();                                in various combinations
//m_adapter.remove(position);

Item toRemove = m_adapter.getItem(position);
m_parts.remove(toRemove); //or, m_parts.remove(position);<-This is what should work
     m_adapter.notifyDataSetChanged();
     loadAdapter();
//       runOnUiThread(new Runnable() {
//      public void run() {
//          m_adapter.notifyDataSetChanged();     <--I've tried a thread approach
//              }  
//          }); 
 }
 break;

 case 4:
 Intent i = new Intent(ActivityMain.this,
 ShowARegularList.class);
 i.putExtra("list_id", (position + 1) + "");
 startActivity(i);
 break;
 }
 }
 });

 alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {

 @Override
 public void onClick(DialogInterface dialog, int which) {

 dialog.dismiss();

 }
 });

 alert.show();
 }

,如果3使用

更改数据库
// Delete single list item data
public boolean deleteList(int id) {
    id++;
    DatabaseHelper helper = new DatabaseHelper(this);
    database = helper.getWritableDatabase();

    // ContentValues values = new ContentValues();
    // values.put("_id", id);

    database.delete("list_data", "_id =" + id, null);
    database.close();

    // text = text.removeElementStr();
    // itemCount--;
    return true;

}

以上方法可以从列表中删除项目,并直观地缩小差距。但是,当点击&#34; old&#34;从中删除项目的位置(这会引发编辑所选项目的新意图),在查询数据库的新活动中引发异常(最后一行,logcat中的97):

final Integer thisListID = Integer.parseInt(listIDstr);
    final DatabaseHelper helper = new DatabaseHelper(this);
    database = helper.getReadableDatabase();

    Cursor cursor = database.query("list_data", new String[] { "listTitle",
            "listContent", "dateCreated", "dateModified" }, "_id = " + thisListID
            + "", null, null, null, null);

    ArrayList<String> listInfo = new ArrayList<String>();

    if (cursor != null && cursor.moveToFirst()) {
        listInfo.add(cursor.getString(cursor.getColumnIndex("listTitle")));
        listInfo.add(cursor.getString(cursor.getColumnIndex("listContent")));
        listInfo.add(cursor.getString(cursor.getColumnIndex("dateCreated")));
        listInfo.add(cursor.getString(cursor.getColumnIndex("dateModified")));
    }

    cursor.close();
    strListContent = listInfo.get(1).trim();

使用logcat

java.lang.RuntimeException: Unable to start activity... 
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2049)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2083)
at android.app.ActivityThread.access$600(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1233)
...
at com.baked.listanywhere.ShowARegularList.onCreate(ShowARegularList.java:97)

索引小于删除的列表项是正常的;那些索引较大的人的内容是一次性的。我怀疑在查询中我的逻辑错误,查询不再存在的索引......但似乎我应该能够重绘列表并拥有一个镜像数据库的索引列表。我真正想要做的就是消除对列表的任何记忆然后重新填充它,但我似乎无法做到这一点......任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:1)

好吧,因为没有人在喋喋不休,我通过查询解决了这个问题

Cursor cursor = database.rawQuery("SELECT * FROM list_data ORDER BY _id LIMIT 1 OFFSET '"+ thisListID +"'", null);
感谢Wojtek在this question。是的,

case 3:
 if (deleteList(position)) {

     Item toRemove = m_adapter.getItem(position);
     m_parts.remove(toRemove);
     m_adapter.notifyDataSetInvalidated();

     loadAdapter();

 break;
 }

工作正常,即使我能宣誓就是这个问题!