Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android SQLiteDatabase-从数据库中删除值后Listview和数据库ID不匹配_Java_Android_Database_Sqlite_Listview - Fatal编程技术网

Java Android SQLiteDatabase-从数据库中删除值后Listview和数据库ID不匹配

Java Android SQLiteDatabase-从数据库中删除值后Listview和数据库ID不匹配,java,android,database,sqlite,listview,Java,Android,Database,Sqlite,Listview,大家好,我是android数据库的新手。我遵循这个网站的教程。下面的代码是关于添加、更新、删除数据库中的名称。 一切正常。我可以从数据库中添加、更新和删除姓名。 问题: 例如,我添加了4个名称 ID name 1 A 2 B 3 C 4 D 当我删除一个文件时,它会从listview和数据库中删除。它在listview中更新。 现在数据库看起来像这样 ID name 1 null 2 B 3 C 4 D B C D Listview是这样的 ID name

大家好,我是android数据库的新手。我遵循这个网站的教程。下面的代码是关于添加、更新、删除数据库中的名称。

一切正常。我可以从数据库中添加、更新和删除姓名。

问题: 例如,我添加了4个名称

ID name 
1   A
2   B
3   C
4   D
当我删除一个文件时,它会从listview和数据库中删除。它在listview中更新。 现在数据库看起来像这样

ID name 
1  null
2   B
3   C
4   D
B
C
D
Listview是这样的

ID name 
1  null
2   B
3   C
4   D
B
C
D
因此,当我点击B删除或编辑时,它在我的编辑和删除视图中不显示任何内容,但当我点击C时,它在删除视图中显示B

我浏览了stackoverflow中所有可用的解决方案,我知道这是重复的问题,但是对于这个例子有什么解决方案吗。 我想当我点击B时,它应该显示B不为空,当我点击C时,它应该显示C,删除A后

注意:任何人都可以修改代码吗。我非常确定有许多开发人员正在寻找解决此问题的方法。特别是像我这样的初学者。这将是很大的帮助。提前谢谢你

DBHelper

    public Integer deleteContact (Integer id) {
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete("contacts",
            "id = ? ",
            new String[] { Integer.toString(id) });
}

public ArrayList<String> getAllCotacts() {

    ArrayList<String> array_list = new ArrayList<String>();
    //hp = new HashMap();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res =  db.rawQuery( "select * from contacts", null );
    res.moveToFirst();

    while(res.isAfterLast() == false){
        array_list.add(res.getString(res.getColumnIndex(CONTACTS_COLUMN_NAME)));
        res.moveToNext();
    }
    return array_list;
}
问题 onItemClickListener的第三个参数(arg2)是位置(第四个参数也是位置,除非使用光标适配器)

位置永远不会等同于id(除非您强制id具有某些值),这是因为第一项的位置为0。第一行的id将为1。如果您开始删除行,那么生活就会变得更加复杂,正如您所发现的那样

解析(理论上) 您需要做的是获得正确的id

您可以使用一个免费的long数组列表
ArrayList
或一个long数组
long[]
(您需要两种方法来构建
ArrayList
ArrayList
long[]
)。但是,如果您使用了过滤器,那么这也可能是不同步的因此,不建议使用这种方法。

您可以使用游标适配器和游标作为ListView的源,然后第四个参数将是id(需要一个名为\u id的列,它应该是行的id我建议使用游标,因为不需要中间对象

您可以使用对象的ArrayList
ArrayList
,在这种情况下,对象将至少有两个成员idname。然后,您可以使用适配器的
getItem(arg2)
方法检索对象,然后从对象中获取id

使用2个解决方案的工作示例 以下是显示3个列表视图的应用程序的代码:第一个由字符串ArrayList(您当前拥有的内容)生成,第二个由对象ArrayList(适当的对象,即MyTableObject ArrayList)生成,第三个通过光标生成。显示的数据相同

单击项目显示可获得的值(可传递给删除的值)

  • 第一个ListView只能获取并显示位置(就好像它是ID一样)
  • 第二个列表视图显示从对象获得的ID和从位置获得的ID(它们不匹配)
  • 第三个列表视图显示通过光标获得的ID(相当于对象)和从第四个参数获得的ID,它们始终匹配

  • 注意每次运行应用程序时都会添加更多数据。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    DatabaseHelper mDBHlpr;

    ListView mListView01,mListVeiw02,mListView03;

    ArrayAdapter<String> mAdapterStringArrayList;
    ArrayAdapter<MyTableObject> mAdapterMyTableObjectArrayList;
    SimpleCursorAdapter mAdapterCursor;

    ArrayList<String> mMyTableListAsStrings;
    ArrayList<MyTableObject> mMyTableAsObjects;
    Cursor mMyTableListAsCursor;

    Context mContext;

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

        mListView01 = this.findViewById(R.id.listview01);
        mListVeiw02 = this.findViewById(R.id.listview02);
        mListView03 = this.findViewById(R.id.listview03);

        mDBHlpr = new DatabaseHelper(this);
        mDBHlpr.addRow("Fred");
        mDBHlpr.addRow("Bert");
        mDBHlpr.addRow("Harry");
        mDBHlpr.addRow("Fred");

        //String Array List
        mMyTableListAsStrings = mDBHlpr.getAllAsStringArrayList();
        mAdapterStringArrayList = new ArrayAdapter<>(
                this,
                android.R.layout.simple_list_item_1,
                mMyTableListAsStrings
        );
        mListView01.setAdapter(mAdapterStringArrayList);


        //Object Array List
        mMyTableAsObjects = mDBHlpr.getAllAsMyTableObjectArrayList();
        mAdapterMyTableObjectArrayList = new ArrayAdapter<>(
                this,
                android.R.layout.simple_list_item_1,
                mMyTableAsObjects
        );
        mListVeiw02.setAdapter(mAdapterMyTableObjectArrayList);

        // Cursor
        mMyTableListAsCursor = mDBHlpr.getAllAsCursor();
        mAdapterCursor = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_1,
                mMyTableListAsCursor,
                new String[]{DatabaseHelper.COL_MYTABLE_NAME},
                new int[]{android.R.id.text1},
                0
        );
        mListView03.setAdapter(mAdapterCursor);


        mListView01.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                String name = mAdapterStringArrayList.getItem(position);
                Toast.makeText(
                        mContext,
                        "Name is " + name  +
                                ". ID is " + String.valueOf(id) +
                                " (note may not match)",
                        Toast.LENGTH_SHORT
                ).show();
            }
        });

        mListVeiw02.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                MyTableObject mytable = mAdapterMyTableObjectArrayList.getItem(position);
                String name = mytable.getName();
                long id_in_object = mytable.getId();
                Toast.makeText(
                        mContext,
                        "Name is " + name  +
                                ". ID from object is " + String.valueOf(id_in_object) +
                                ". ID from adapter is " + String.valueOf(id),
                        Toast.LENGTH_SHORT
                ).show();
            }
        });

        mListView03.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                Cursor csr = mAdapterCursor.getCursor(); // already positioned
                String name = csr.getString(csr.getColumnIndex(DatabaseHelper.COL_MYTABLE_NAME));
                long id_in_cursor = csr.getLong(csr.getColumnIndex(DatabaseHelper.COl_MYTABLE_ID));
                Toast.makeText(
                        mContext,
                        "Name is " + name  +
                                ". ID from object is " + String.valueOf(id_in_cursor) +
                                ". ID from adapter is " + String.valueOf(id),
                        Toast.LENGTH_SHORT
                ).show();
            }
        });
    }
}
public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TB_MYTABLE = "mytable";
    public static final String COl_MYTABLE_ID = BaseColumns._ID; //<<<< use standard android id column name
    public static final String COL_MYTABLE_NAME = "_name";

    private static final String mytable_crtsql =
            "CREATE TABLE IF NOT EXISTS " + TB_MYTABLE +
                    "(" +
                    COl_MYTABLE_ID + " INTEGER PRIMARY KEY, " +
                    COL_MYTABLE_NAME + " TEXT " +
                    ")";

    SQLiteDatabase mDB;

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

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

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

    }

    public long addRow(String name) {
        ContentValues cv = new ContentValues();
        cv.put(COL_MYTABLE_NAME,name);
        return mDB.insert(TB_MYTABLE,null,cv);
    }

    public ArrayList<String> getAllAsStringArrayList() {
        ArrayList<String> rv = new ArrayList<>();
        Cursor csr = mDB.query(
                TB_MYTABLE,
                null,
                null,
                null,
                null,
                null,
                null
        );
        while (csr.moveToNext()) {
            rv.add(csr.getString(csr.getColumnIndex(COL_MYTABLE_NAME)));
        }
        csr.close();
        return rv;
    }

    public ArrayList<MyTableObject> getAllAsMyTableObjectArrayList() {
        ArrayList<MyTableObject> rv = new ArrayList<>();
        Cursor csr = mDB.query(
                TB_MYTABLE,
                null,
                null,
                null,
                null,
                null,
                null
        );
        while (csr.moveToNext()) {
            rv.add(new MyTableObject(
                    csr.getLong(csr.getColumnIndex(COl_MYTABLE_ID)),
                    csr.getString(csr.getColumnIndex(COL_MYTABLE_NAME))
                    )
            );
        }
        csr.close();
        return rv;
    }

    public Cursor getAllAsCursor() {
        return mDB.query(
                TB_MYTABLE,
                null,
                null,
                null,
                null,
                null,
                null
        );
    }
}
public class MyTableObject {
    private long id;
    private String name;

    public MyTableObject(long id, String name) {
        this.id = id;
        this.name = name;
    }

    public long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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


    /*
        NOTE toString method returns just the name
     */
    @Override
    public String toString() {
        return name;
    }
}
活动\u main.xml

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="ArrayList-String"
            />
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="ArrayList-object"
            />
        <TextView
            android:text="Cursor"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <ListView
            android:id="@+id/listview01"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:background="#ffffaaaa">
        </ListView>
        <ListView
            android:id="@+id/listview02"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:background="#ffaaffaa">
        </ListView>
        <ListView
            android:id="@+id/listview03"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:background="#ffaaaaff">
        </ListView>
    </LinearLayout>

</LinearLayout>
DatabaseHelper.java已更改为包含一个新方法,用于根据id

i、 e.增加了以下方法:-

public int delete(long id) {
    String whereclause = COl_MYTABLE_ID + "=?";
    String[] whereargs = new String[]{String.valueOf(id)};
    return mDB.delete(TB_MYTABLE,whereclause,whereargs);
}
问题 onItemClickListener的第三个参数(arg2)是位置(第四个参数也是位置,除非使用光标适配器)

位置永远不会等同于id(除非您强制id具有某些值),这是因为第一项的位置为0。第一行的id将为1。如果您开始删除行,那么生活就会变得更加复杂,正如您所发现的那样

解析(理论上) 您需要做的是获得正确的id

您可以使用一个免费的long数组列表
ArrayList
或一个long数组
long[]
(您需要两种方法来构建
ArrayList
ArrayList
long[]
)。但是,如果您使用了过滤器,那么这也可能是不同步的因此,不建议使用这种方法。

您可以使用游标适配器和游标作为ListView的源,然后第四个参数将是id(需要一个名为\u id的列,它应该是行的id我建议使用游标,因为不需要中间对象

您可以使用对象的ArrayList
ArrayList
,在这种情况下,对象将至少有两个成员idname。然后,您可以使用适配器的
getItem(arg2)
方法检索对象,然后从对象中获取id

使用2个解决方案的工作示例 以下是显示3个列表视图的应用程序的代码:第一个由字符串ArrayList(您当前拥有的内容)生成,第二个由对象ArrayList(适当的对象,即MyTableObject ArrayList)生成,第三个通过光标生成。显示的数据相同

单击项目显示可获得的值(可传递给删除的值)

  • 第一个ListView仅显示位置ca
    public int delete(long id) {
        String whereclause = COl_MYTABLE_ID + "=?";
        String[] whereargs = new String[]{String.valueOf(id)};
        return mDB.delete(TB_MYTABLE,whereclause,whereargs);
    }