【问题标题】:Android Arraylist item idAndroid Arraylist 项目 ID
【发布时间】:2014-01-10 15:47:17
【问题描述】:

我作为 .Net 开发人员已经超过 12 年,并且是 Android 新手,所以这些概念与我相似,但我一直在谷歌上搜索很多细节(和术语)...

这是我的问题 - 我正在使用 Cursor 查询 SQLite 以获取特定表的所有记录,以填充已被类型转换为我创建的对象的 ArrayList。从那里我使用 ArrayAdapter 来填充 ListView。从那里长按,我有一个监听器,它有一个上下文菜单,其中包含编辑和删除等选项。为了做到这些,你需要有原始的 SQLite _id,我读到你可以通过使用 AdapterView.AdapterContextMenuInfo 信息然后简单地使用 info.id 来获得它。

在调试器中,我注意到它始终设置为 0。所以当我在调试器中构建 ArrayList 时,我再往前走,发现一直回到查询,每个项目都有我查询中的所有字段信息,除了 _id .它确实有一个 id 字段,但它始终设置为 0。我假设这是我必须设置的字段才能传递 id,但没有提供这样做的方法。 下面是我的 SQLite 查询:

public ArrayList<Books> getAllBooks(){
        ArrayList<Books> itemList = new ArrayList<Books>();

        String sqlQuery =
                "Select "
                + KEY_ID + ", "
                + title + ", "
                + description + ", "
                + genre + ", "
                + creation_dt + ", "
                + modification_dt
                + " From "
                + TABLE_Books;

        Cursor cursor = database.rawQuery(sqlQuery, null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            //itemList.add(new Books(cursor.getInt(0), cursor.getString(1), cursor.getString(2)));
            String logId = String.valueOf(cursor.getInt(0));
            Log.i("Book ID", "Book Title: " + cursor.getString(1) + " KEY_ID: " + logId);
            itemList.add(cursorToBook(cursor));
            cursor.moveToNext();
        }
        cursor.close();
        return itemList;
    }

    private Books cursorToBook(Cursor cursor){
        Books book = new Books();
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss aa");
        book.setId(cursor.getInt(0));
        book.setTitle(cursor.getString(1));
        book.setDescription(cursor.getString(2));
        book.setGenre(cursor.getString(3));
        return book;
    }

这是我的 Books 对象:

public class Books {
    public int _id;
    private String title;
    private String description;
    private String genre;
    private Date creation_dt;
    private Date modification_dt;

    public int getId(){ return _id;}
    public void setId(int Id){ this._id = _id;}

    public String getTitle(){ return title;}
    public void setTitle(String title){ this.title = title;}

    public String getDescription(){ return description;}
    public void setDescription(String description){ this.description = description;}

    public String getGenre(){ return genre;}
    public void setGenre(String genre){ this.genre = genre;}

    public Date getCreation_dt(){ return creation_dt;}
    public void setCreation_dt(Date creation_dt){ this.creation_dt = creation_dt;}

    public Date getModification_dt(){ return modification_dt;}
    public void setModification_dt(Date modification_dt){ this.modification_dt = modification_dt;}

}

非常感谢您花时间回复! 谢谢。

更新: 我的 SQLiteOpenHelper -

public class SQLiteHelper extends SQLiteOpenHelper{

    //Database
    private static final String Database_Name = "novel.db";
    private static final int Database_Version = 1;

    // Table Names
    public static final String TABLE_Books = "books";
    public static final String TABLE_Chapter = "chapters";
    public static final String TABLE_major_Character = "master_character";

    //Common Columns
    public static final String column_id = "_id";

    //Book Columns
    public static final String book_title = "title";
    public static final String book_description = "description";
    public static final String book_genre = "genre";
    public static final String book_creation_dt = "creation_dt";
    public static final String book_modification_dt = "modification_dt";

    //Chapter Columns
    public static final String chapter_chapter_num = "chapter_num";
    public static final String chapter_chapter_title = "chapter_title";
    public static final String chapter_start_page = "start_page";
    public static final String chapter_end_page = "end_page";
    public static final String chapter_total_pages = "total_pages";
    public static final String chapter_synopsis = "synopsis";
    public static final String chapter_book_id = "book_id";

    //Master Character Columns
    public static final String mc_name = "name";
    public static final String mc_role = "role";
    public static final String mc_age = "age";
    public static final String mc_pertinent_info = "pertinent_info";
    public static final String mc_relevant_backstory = "relevant_backstory";

    public static final String book_create = "create table " + TABLE_Books
            + " ("
            + column_id + " integer primary key autoincrement, "
            + book_title + " varchar(1000), "
            + book_description + " varchar(100), "
            + book_creation_dt + " datetime, "
            + book_modification_dt + " datetime, "
            + book_genre + " varchar(250) "
            + ")";

    public static final String chapters_create = "create table " + TABLE_Chapter
            + " ("
            + column_id + " integer primary key autoincrement, "
            + chapter_chapter_num + " int, "
            + chapter_chapter_title + " varchar(1000), "
            + chapter_start_page + " int, "
            + chapter_end_page + " int, "
            + chapter_total_pages + " int, "
            + chapter_synopsis + " varchar(1000), "
            + chapter_book_id + " int"
            + ")";
    public static final String master_character_create = "create table " + TABLE_major_Character
            + " ("
            + column_id + " integer primary key autoincrement, "
            + mc_name + " varchar(1000), "
            + mc_role + " varchar(1000), "
            + mc_age + " int, "
            + mc_pertinent_info + " varchar(1000), "
            + mc_relevant_backstory + " varchar(1000) "
            + ")";

public SQLiteHelper(Context context){
    super (context, Database_Name, null, Database_Version );
}

    @Override
    public void onCreate(SQLiteDatabase database){
        database.execSQL(book_create);
        database.execSQL(chapters_create);
        database.execSQL(master_character_create);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(SQLiteHelper.class.getName(),
                "Upgrading database from version " + oldVersion + " to "
                        + newVersion + ", THIS WILL DESTROY ALL OLD DATA!");
        db.execSQL("drop table if exists " + TABLE_Books);
        db.execSQL("drop table if exists " + TABLE_Chapter);
        db.execSQL("drop table if exists " + TABLE_major_Character);
        onCreate(db);
    }
}

更新: 我的插入方法

public void createBook(Books book){
        SimpleDateFormat s = new SimpleDateFormat("ddMMyyyyhhmmss");
        String newDate = s.format(new Date());
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(title, book.getTitle());
        values.put(description, book.getDescription());
        values.put(genre, book.getGenre());
        values.put(creation_dt, newDate);

        long book_id = db.insert(TABLE_Books, null, values);
    }

【问题讨论】:

  • 您能发布您的 CREATE TABLE 语句吗?
  • 感谢您花时间查看我的问题。我已经用我的 SQLiteOpenHelper 扩展更新了这篇文章。
  • 自动增量没问题。当您向该表添加信息时,inserts 语句怎么样?
  • 我用我的插入命令进行了更新。当我注意到这个问题时,在我的 Select Query 中,您可以看到我在哪里 log.d 书名和 ID。实际上有一个值(例如2)。此外,在调试项目 0 处的光标时有一个值。我显然不了解 ArrayLists,但在我在查询中执行 itemList.add 之前,id 一直存在。在调试器中查看它,每个项目都已填充,但每个项目的 id = 0。
  • 我以为你的问题出在数据库上,而你从那里得到 0 作为 _id。

标签: android sqlite arraylist


【解决方案1】:

使用CursorAdapter 代替ArrayAdapter,可以节省大量代码。

类似:

String sqlQuery =
            "Select "
            + KEY_ID + ", "
            + title + ", "
            + description + ", "
            + genre + ", "
            + creation_dt + ", "
            + modification_dt
            + " From "
            + TABLE_Books;

    Cursor cursor = database.rawQuery(sqlQuery, null);

    String[] from = {KEY_ID, title}; // _id mandatory
    int[] to = new int[]{android.R.id.text1};

    CursorAdapter adapter = new SimpleCursorAdapter(
       context,
       android.R.layout.simple_list_item_1,
       cursor,
       from,
       to,
       CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

    ListView listView = ....
    listView.setAdapter(adapter);

【讨论】:

  • 这已经是漫长的一天......从数据库中获取数据不应该这么难。 Android 还有很长的路要走......所以我所做的是使用 SQLiteCursorLoader(自定义库)。当我在列表视图中使用多个字段时,我的事情变得非常复杂。话虽这么说,你让我走上了正确的道路,我非常感激。但是,我认为您不能像在您的示例中那样简单地将光标添加到 CursorAdapter ......但我是新手,可能是错的......我非常感谢!谢谢
【解决方案2】:

错误在setId中。你做This._id = _id应该是This._id = Id

此外,键值是 long 而不是 int
最佳做法是避免在 cursor.getLong(0) 上使用 0

改变

book.setId(cursor.getInt(0));

cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)); 

然后将getIdsetId方法签名改为long。

所有更改后,类 Books 将是这样的:

public class Books {

    public long _id;

    ........

    public long getId(){ return _id;}
    public void setId(long Id){ this._id = Id;}

    ........
}

【讨论】:

  • 感谢您的回复!我决定放弃接受的答案中列出的对象方法。我在想 .Net(其中包括从数据中获取数据很容易)...我要感谢您抽出宝贵的时间来回答!
  • 是的,cursorAdapter 是最好的方法。
【解决方案3】:

itemList.add(cursorToBook(cursor));之后添加这个sn-p,

Book testBook = itemList.get(itemList.size()-1);
Log.i("ID of recently inserted book is " + testBook.getId());

检查这是否仍然打印值“0”。

AdapterView.AdapterContextMenuInfo 的 id 是 ListAdapter 对象(在您的情况下为 ArrayAdapter)中的项目(即 Book 对象)的 rowid。如果上面的 Log.i 打印出正确的 id,那么不要使用 ArrayAdapter,而是创建 BaseAdapter 的新子类(并正确覆盖 getItemId 方法)或者只使用 CursorAdapter。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2021-04-04
    相关资源
    最近更新 更多