【问题标题】:Android Databases: Help need with deleting items from database-populated ListViewAndroid 数据库:帮助需要从数据库填充的 ListView 中删除项目
【发布时间】:2014-11-07 19:34:55
【问题描述】:

我有一个使用本地存储数据库填充的 ListView。当您单击列表项时,它会将您带到 viewArtist 活动,该活动根据您单击的项目的 ROW_ID 用行条目信息填充 textView 框。这是使用 putExtra() 完成的。 viewArtist 活动有一个用于删除条目的按钮。当您删除条目时,列表不会刷新,因此您必须关闭应用程序并返回。

但我的主要问题是在删除一个项目时,列表不再显示该条目,但是当您单击代替已删除条目的条目时,下一个屏幕的 editText 视图中不会显示任何信息。不仅如此,当您单击任何跟在此条目之后的列表条目时,它会在 textViews 中填充上一个列表条目的信息。

这是一张图片来说明我要解释的内容。

图一:http://i.imgur.com/RsXyygF.jpg

似乎该行正在被删除,但列表仍然将每个 ROW_ID 与列表项匹配,并且没有自动递减。

任何帮助将不胜感激,因为我几天来一直在努力解决这个问题! 提前致谢!

这里是调用 viewArtist 类的 mainActivity 类:

package com.example.msdproject;

import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.content.Intent;
import android.widget.ListView;  
import android.widget.Button;
import android.widget.ArrayAdapter;
import android.view.View;
import java.sql.SQLException;
import java.util.ArrayList;


public class MainActivity extends ListActivity {

public ArrayList<String> data_list=new ArrayList<String>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button btn = (Button)findViewById(R.id.addConcertButton);
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(MainActivity.this, AddArtist.class);
            startActivity(i);
        }
    });

    DBManager db =  new DBManager(this);

    try {
        db.open();
    } catch (SQLException e) {
        e.printStackTrace();
    }

    ListView listView = (ListView) findViewById(android.R.id.list);
    Cursor c = db.getAllConcerts();
    if (c.moveToFirst())
    {
        do {
            data_list.add(c.getString(0));
        } while (c.moveToNext());
    }
    ArrayAdapter<String> concertList=new ArrayAdapter<String>(getApplicationContext(),       android.R.layout.simple_list_item_1, data_list);
    listView.setAdapter(concertList);
    concertList.notifyDataSetChanged();

    db.close();
}

protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    Intent i =  new Intent(MainActivity.this, ViewArtist.class);
    String strLong = Long.toString(id);
    //String idString = Objects.toString(id, null);

    if(strLong == "null")
    {
        id = id + 1;
        i.putExtra("id", id);
        startActivity(i);

    }

    else
    {
        i.putExtra("id", id);
        startActivity(i);
    }


}

}

这是我的 ViewArtist 课程:

package com.example.msdproject;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.sql.SQLException;


public class ViewArtist extends Activity {

    DBManager db = new DBManager(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_artist);

        Intent intent = getIntent();
        final long num = intent.getLongExtra("id", 1);

        Button btn = (Button)findViewById(R.id.updateConcertButton);
        btn.setOnClickListener(new View.OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                Intent i = new Intent(ViewArtist.this, UpdateArtist.class);
                i.putExtra("id", num);
                startActivity(i);
            }
        });

        String name;
        String venue;
        String date;
        String comments;

        try {
            db.open();
            Cursor c = db.getConcert(num + 1);
            //The reason I have num + 1 is because List Item 1 has a ROW_ID of 0
            if (c.moveToFirst())
            {
                do
                {
                    name = (c.getString(1));
                    venue = (c.getString(2));
                    date = (c.getString(3));
                    comments = (c.getString(4));

                    TextView nameTxt = (TextView)findViewById(R.id.viewName);
                    TextView titleTxt = (TextView)findViewById(R.id.viewTitle);
                    TextView venueTxt = (TextView)findViewById(R.id.viewVenue);
                    TextView dateTxt = (TextView)findViewById(R.id.viewDate);
                    TextView commentsTxt = (TextView)findViewById(R.id.viewComments);

                    nameTxt.setText(name);
                    titleTxt.setText("ROW_ID: " + String.valueOf(num));
                    venueTxt.setText(venue);
                    dateTxt.setText(date);
                    commentsTxt.setText(comments);

                    Button btn2 = (Button)findViewById(R.id.deleteConcertButton);
                    btn2.setOnClickListener(new View.OnClickListener()
                    {

                        @Override
                        public void onClick(View v) {
                            db.deleteConcert(num);

                        }
                    });

                } while (c.moveToNext());
            }
        }

        catch (SQLException e)
        {
            e.printStackTrace();
        }

        db.close();

    }
}

这是我的 DBManager 类:

package com.example.msdproject;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;

import java.sql.SQLException;


public class DBManager {

    public static final String COL_ROWID = "_id";
    public static final String COL_NAME = "name";
    public static final String COL_VENUE = "venue";
    public static final String COL_DATE = "date";
    public static final String COL_COMMENTS = "comments";

    private static final String DB_NAME = "Concerts";
    private static final String DB_TABLE = "Concert_Info";
    private static final int DB_VERSION = 1;

    private static final String DB_CREATE =
            "create table " + DB_TABLE + 
    " (_id integer primary key autoincrement, " +
            "name text not null, " +
            "venue text not null, " +
            "comments text not null, " +
            "date text not null);";

    private final Context context;

    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    public DBManager(Context ctx)
    {
        this.context = ctx;
        DBHelper = new DatabaseHelper(context);
    }

    //embedded class
    public static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            db.execSQL(DB_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            /*
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("drop table if exists Concert_Info");
            onCreate(db);*/
        }
    }

    public DBManager open() throws SQLException
    {
        db = DBHelper.getWritableDatabase();
        //db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE + ";");
        return this;
    }

    public void close()
    {
        DBHelper.close();
    }

    public long getId(String name)
    {
        long x = 10;
        return x;
    }
    public long insertConcert(String name, String venue, String date, String comments)
    {
        ContentValues initialValues = new ContentValues();
        initialValues.put(COL_NAME, name);
        initialValues.put(COL_VENUE, venue);
        initialValues.put(COL_DATE, date);
        initialValues.put(COL_COMMENTS, comments);
        return db.insert(DB_TABLE, null, initialValues);
    }

    public boolean deleteConcert(long ROW_ID)
    {
        return db.delete(DB_TABLE, COL_ROWID + "=" + ROW_ID, null) > 0;
    }

    public Cursor getAllConcerts() {
        return db.query(DB_TABLE, new String[]
                        {
                                COL_NAME,
                                COL_VENUE,
                                COL_DATE,
                                COL_COMMENTS
                        },
                        null,
                        null,
                        null,
                        null,
                        null
                );
    }

    public Cursor getConcert(long ROW_ID) throws SQLException
    {
        Cursor mCursor =
                db.query(DB_TABLE, new String[]
                        {
                                COL_ROWID,
                                COL_NAME,
                                COL_VENUE,
                                COL_DATE,
                                COL_COMMENTS
                        },
                        COL_ROWID + "=" + ROW_ID,
                        null,
                        null,
                        null,
                        null
                );
        if (mCursor != null)
        {
            mCursor.moveToFirst();
        }

        return mCursor;

    }


    public boolean updateConcert(long ROW_ID, String name, String venue, String date, String comments)
    {
        ContentValues args = new ContentValues();
        args.put(COL_NAME, name);
        args.put(COL_VENUE, venue);
        args.put(COL_DATE, date);
        args.put(COL_COMMENTS, comments);
        return db.update(DB_TABLE, args, COL_ROWID  + "=" + ROW_ID, null) > 0;

    }

}

【问题讨论】:

  • 您的 arrayAdapter 不知道您的数据的 db id 是什么。你得到的 id 是列表中的位置。
  • 我明白了。这是因为 data_list 将进入 ArrayAdapter 吗?你能建议一个可能的解决方法吗?
  • 您可以使用光标适配器。如果 id 是光标的第一列(您需要修改 getAllConcerts 中的 projectino),那么 onItemClick 将包含正确的值
  • @njzk2 您能否通过修改 getAllConcerts() 中的 projectino 来解释您的意思? id 是光标中的第一列

标签: android database sqlite listview android-listview


【解决方案1】:

您需要向呈现列表的片段或活动中的 onResume 添加代码以更新光标,并更新列表视图以删除已删除的值

您似乎还向现有列表添加了一个新列表。在 OnResume 中,您需要做的是更新 data_list 并调用 ConcertList.notifyDataSetChanged();。对于来自数据库的列表,我使用 CursorAdapter 而不是数组适配器,因为你正在这样做,实际的机制不是 100% 熟悉

【讨论】:

    【解决方案2】:

    两件事,关于 db id 与列表位置的评论是正确的。您将需要查询数据库,而不是基于列表中的位置,而是基于列表中的值。 (即如果它是唯一的)以便从数据库中获取详细视图/记录。

    第二个/第一个是当您选择列表并转到详细视图时,列表活动没有消失/没有被破坏,因此当您返回列表时,它仍会显示先前查询的值.

    您需要将代码添加到呈现列表的片段或活动中的 onResume 以更新光标并更新列表视图以删除已删除的值

    【讨论】:

    • 感谢您的回复!到目前为止,我已经尝试在单击项目后将 ListView 适配器设置为 null,然后在新创建的 onResume() 方法中再次运行光标。但问题是当我返回初始屏幕时,每次返回 MainActivity 屏幕时都会一次又一次地附加一个新列表。你能给我一些关于如何解决这个问题的见解吗?
    • 似乎您可能正在将新列表添加到现有列表中。在 OnResume 中,您需要做的是更新 data_list 并调用 ConcertList.notifyDataSetChanged();。对于来自数据库的列表,我使用 CursorAdapter 而不是 Array 适配器,因为你正在这样做,实际的机制对我来说不是 100% 熟悉。但是,您需要做的是更新列表,然后运行 ​​notifyDataSetChanged。不确定您是否需要对适配器做任何事情,否则它只会处理所有事情
    • 我已经为此编辑了 onResume 方法,但我仍然遇到同样的问题。
    • @Override public void onResume() { super.onResume(); ConcertList.clear(); data_list.clear();试试 { db.open();光标 c = db.getAllConcerts(); if (c.moveToFirst()) { do { data_list.add(c.getString(1)); } 而 (c.moveToNext()); } ConcertList.notifyDataSetChanged(); } catch (SQLException e) { e.printStackTrace(); } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    相关资源
    最近更新 更多