通过ListView在SQLIte中删除数据

时间:2018-06-24 13:54:05

标签: android listview android-sqlite delete-row

我想通过ListView在数据库中删除一行。我已经设法在列表视图中显示数据。我正在使用OnItemLongClickListener,然后打开一个对话框来删除单击的项目。我无法使用实际的删除方法。

OnCLickListener方法:

public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long id) {
            build = new AlertDialog.Builder(ZeigeFaecherListe.this);
            build.setTitle("Fach löschen?" + faecherListe.get(position));
            build.setMessage("Willst du das Fach wirklich löschen?");

            build.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.cancel();
                }
            });

            build.setPositiveButton("Löschen", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialogInterface, int i) {
                    myDb.loescheFach(position);

                    Toast.makeText(getApplicationContext(), faecherListe.get(position) + " gelöscht.", Toast.LENGTH_LONG).show();
                    myDb.zeigeFaecher();
                    dialogInterface.cancel();
                }
            });

            AlertDialog alert = build.create();
            alert.show();
        return true;
        }
    });

实际的删除方法:

public int loescheFach(int position){
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete("Fach_table","FACHID=?", new String[]{String.valueOf(position)});
}

3 个答案:

答案 0 :(得分:0)

您将列表位置与ID混淆,它们可能不匹配。

将您的myDb.loescheFach(position);更改为myDb.loescheFach(id);

答案 1 :(得分:0)

您正在将ArrayList的位置传递给SQLite以便删除语句。您应将FACHID(以您的情况为准)作为删除语句的参数。

由于您发布的代码不完整,因此我将其假定如下。

....
....

build.setPositiveButton("Löschen", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
               // myDb.loescheFach(position);

               // first get an id from ArrayList using position faecherListe.get(position)

               // then pass that id to your method 
               myDb.loescheFach(id);

                Toast.makeText(getApplicationContext(), faecherListe.get(position) + " gelöscht.", Toast.LENGTH_LONG).show();
                myDb.zeigeFaecher();
                dialogInterface.cancel();
            }
        });

....
....

答案 2 :(得分:0)

第一个位置将不等于表中行的 rowid / id 。假设您有一个定义为your_id_column INTEGER PRIMARY KEY id 列(或使用AUTOINCREMENT关键字,没有什么实际区别),并且您未指定值插入一行时,第一个 id 可能是1,然后是2,然后是3 ...,等等。

但是,列表中第一项的 position (传递给onItemClick / onItemLongClick的第三个参数)将为0,然后是1,然后是2,依此类推。因此,您将永远不会真正删除正确的行(单击第一项不会删除任何内容,单击第二项将会删除第一项),并且在删除行时,它会变得更加不同步。

传递的第四个参数( long id )将是 rowid / id,并且仅在使用CursorAdapter的情况下(即,Cursor是ListView的源数据) )。在这种情况下,游标必须具有名为 _id 的列。但是,似乎 faecherListe 是源,并且当您使用 get 方法时,它似乎是ArrayList / List。因此,传递的 id 值将与 position 相同,只是它的长度较长。

现在,如果 faecherListe ArrayList<object_that_reflects_the_columns_of_the_table_including_id>,则假定您可以使用long retrieved_id = faecherListe.get(position).getId()的getId的获取方法。但是,评论:-

  

我猜你有String的ArrayList,这就是为什么要获取String   ArrayList中的值– Shashanth 10小时前

     

您仅拥有ArrayList,因此除非确定String所保存的任何数据都是唯一的,否则无法确定id。

示例

这是使用 object_that_reflects_the_columns_of_the_table_including_id 的示例,在这种情况下,该 Feacher 类仅具有名称,并且 id

Feacher.java

这是一个全新的类,它使您可以拥有带有所有相关数据/字段/列(特别是 id 列)的ArrayList。 也就是说,您可以拥有ArrayList

public class Feacher {

    private String name;
    private long id;

    public Feacher(String feacher_name) {
        this(feacher_name,-1);
    }

    public Feacher(String feacher_name, long feacher_id) {
        this.name = feacher_name;
        this.id = feacher_id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String toString() {
        return name + " ID(" + String.valueOf(id) + ")";
    }
}

DBHelper

这是数据库助手(SQLiteOpenHelper的子类):-

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "feacher.db";
    public static final int DBVERSION = 1;

    public static final String TB_FEACHER = "feacher";
    public static final String COL_FEACHER_ID = BaseColumns._ID;
    public static final String COL_FEACHER_NAME = "feacher_name";

    SQLiteDatabase mDB;


    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crtsql = "CREATE TABLE IF NOT EXISTS " + TB_FEACHER +
                "(" +
                COL_FEACHER_ID + " INTEGER PRIMARY KEY," +
                COL_FEACHER_NAME + " TEXT" +
                ")";
        db.execSQL(crtsql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

    public long addFeacher(String feacher_name) {
        ContentValues cv = new ContentValues();
        cv.put(COL_FEACHER_NAME,feacher_name);
        return mDB.insert(TB_FEACHER,null,cv);
    }

    public ArrayList<Feacher> getAllAsFeacherArrayList() {
        ArrayList<Feacher> rv = new ArrayList<>();
        Cursor csr = mDB.query(
                TB_FEACHER,
                null,
                null,
                null,
                null,
                null,
                null
        );
        while (csr.moveToNext()) {
            rv.add(new Feacher(
                    csr.getString(csr.getColumnIndex(COL_FEACHER_NAME)),
                    csr.getLong(csr.getColumnIndex(COL_FEACHER_ID))
                    )
            );
        }
        return rv;
    }

    public int deleteFeacher(long id) {
        return mDB.delete(
                TB_FEACHER,
                COL_FEACHER_ID + "=?"
                ,new String[]{String.valueOf(id)}
                );
    }
}
  • deleteFeacher方法根据其 id
  • 删除行
  • addFeacher方法允许添加一些测试数据。
  • getAllAsFeacherArrayList将所有数据作为ArrayList返回(注意使用设置 id 的构造函数)

MainActivity.java

具有ListView的活动。

public class MainActivity extends AppCompatActivity {

    ListView mListView;
    ArrayAdapter<Feacher> mAdapter;
    DBHelper mDBHlpr;
    ArrayList<Feacher> mFeacherList;

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

        mListView = this.findViewById(R.id.listview);
        mDBHlpr = new DBHelper(this);
        addDataForTesting();
        displayAdapter();
    }

    private void displayAdapter() {
        if (mFeacherList == null) {
            mFeacherList = mDBHlpr.getAllAsFeacherArrayList();
        } else {
            mFeacherList.clear();
            for (Feacher f: mDBHlpr.getAllAsFeacherArrayList()) {
                mFeacherList.add(f);
                mAdapter.notifyDataSetChanged();
            }
        }
        if (mAdapter == null) {
            mAdapter = new ArrayAdapter<Feacher>(this,android.R.layout.simple_list_item_1,mFeacherList);
            mListView.setAdapter(mAdapter);
            mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                     mDBHlpr.deleteFeacher(mAdapter.getItem(i).getId());
                     displayAdapter();
                    return true;
                }
            });
        }
    }

    private void addDataForTesting() {
        mDBHlpr.addFeacher("Feacher 001");
        mDBHlpr.addFeacher("Feacher 002");
        mDBHlpr.addFeacher("Feacher 003");
    }
}
  • 为简单起见,也为了避免意外删除,请注意onItemLongClick。最重要的是mDBHlpr.deleteFeacher(mAdapter.getItem(i).getId());,它从根据位置单击的项目(对象,Feacher)中获取ID。

activity_main.xml

一个非常基本的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <ListView
        android:id="@+id/listview"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFAAAAFF"
        >
    </ListView>
</LinearLayout>

结果

这是第三次运行后的屏幕截图,因此添加了9行,删除了2行(注意,id的2和5丢失了)。删除后该列表将刷新,因此长按完成后该行几乎立即消失。

enter image description here