从 ListView 项获取 DB-Record ID(带 CursorAdapter 和 DB Helper 的 LV)

Get a DB-Record ID from a ListView item (LV with CursorAdapter and DB Helper)

我正在尝试构建一个简单的应用程序作为学生列表。 MainActivity 由 ListViewEditText 框和一个 'add' Button 组成。 我的 ListView 与自定义 CursorAdapter 连接,应用程序使用自定义 SQLiteOpenHelper 数据库。

点击 'add' 按钮 ->

新记录被插入数据库 ->

DB-Record-ID 新插入的记录在添加的ListView项上更新(通过bindView

我想做的是在单击 ListView 项目时传递 DB 记录 ID ,到一个新的 activity,使用 Intent.putExtra,但不确定如何在被单击的 ListView 项中获取子文本视图? (在 onItemClick 中,为了获取其文本并将其与新 Intent 一起传递给新 activity)

PURPOSE 是在新 activity 中拥有 DB-Record-ID,因为新 activity 允许用户更新成绩参数在记录中(因此,我需要 DB-Record-ID 以便在更新时在我的数据库中更新它)

有人可以提出解决方案吗?这是所需的代码 -

主要活动:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    /* Our DB model to store student objects */
    private SqlDbHelper mDB;

    /* Custom SQL-Adapter to connect our SQL DB to the ListView */
    private SQLAdapter mAdapter;

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

        /* Init fields & needed views */
        mDB = new SqlDbHelper(getApplicationContext());
        mAdapter = new SQLAdapter(getApplicationContext(), mDB.getAllRows(), false);
        final ListView lvStudents = findViewById(R.id.lv_students);
        final EditText etName = findViewById(R.id.et_name);
        final EditText etGrade = findViewById(R.id.et_grade);

        /* Listen to ADD BUTTON clicks */
        findViewById(R.id.button_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                insertNewRecord(etName.getText().toString(), etGrade.getText().toString());
                etName.setText("");
                etGrade.setText("");
            }
        });

        /* Set adapter to LV, Listen to list item clicks */
        lvStudents.setAdapter(mAdapter);
        lvStudents.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent listItemIntent = new Intent(getApplicationContext(), ListItemActivity.class);

                // ????????????
                // listItemIntent.putExtra("_ID",
                //       "Get textview.text containing the param in the CLICKED list item);

                startActivity(listItemIntent);
            }
        });
    }


    /**
     * Creates a list item for a student name + grade
     * @param name
     * @param grade
     * @return the new student id in the DB
     */
    private long insertNewRecord(final String name, final String grade) {
        int gradeInt = -1;
        try {
            gradeInt = Integer.parseInt(grade);
        } catch (NumberFormatException e) {
            Log.w(TAG, "Invalid grade entered: " + grade);
        }

        /* Add the new student to the DB */
        final long id = mDB.insertNewStudent(name, gradeInt);
        mAdapter.changeCursor(mDB.getAllRows());
        return id;
    }
}

不确定是否需要,但以防万一 -

SQL适配器:

final class SQLAdapter extends CursorAdapter {
    private LayoutInflater mInflater;

    public SQLAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        return mInflater.inflate(R.layout.lv_line, viewGroup, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        final String name = cursor.getString(cursor.getColumnIndex(SqlDbHelper.KEY_NAME));
        final int grade = cursor.getInt(cursor.getColumnIndex(SqlDbHelper.KEY_GRADE));
        final long id = cursor.getLong(cursor.getColumnIndex(SqlDbHelper.KEY_ID));

        view.findViewById(R.id.ll_line).setBackgroundColor(Color.RED));
        ((TextView)view.findViewById(R.id.tv_name)).setText(name);
        ((TextView)view.findViewById(R.id.tv_grade)).setText(String.valueOf(grade));
        ((TextView)view.findViewById(R.id.tv_id)).setText(String.valueOf(id));
    }
}

SqlDbHelper:

final class SqlDbHelper extends SQLiteOpenHelper {
    private static final String TAG = "SqlDbHelper";

    /* Database version */
    public static final int VERSION = 1;

    /* Relevant string names, keys represent columns */
    public static final String DB_NAME = "StudentsDB";
    public static final String TABLE_NAME = "students";
    public static final String KEY_ID = "_id";
    public static final String KEY_NAME = "Name";
    public static final String KEY_GRADE = "Grade";

    public SqlDbHelper(Context context) {
        super(context, DB_NAME, null, VERSION);

    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        /* Create sql command to create new table */
        StringBuilder sql = new StringBuilder();
        sql.append("CREATE TABLE " + TABLE_NAME + " (")
                .append(KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,")
                .append(KEY_NAME + " TEXT,")
                .append(KEY_GRADE + " INT")
                .append(")");

        /* Execute our sql command:
         * CREATE TABLE StudentsDB(_id INTEGER PRIMARY KEY, Name TEXT, Grade INT) */
        Log.d(TAG, "Query to form table: " + sql.toString());
        sqLiteDatabase.execSQL(sql.toString());
    }

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

    public long insertNewStudent(final String name, final int grade) {
        ContentValues cv = new ContentValues();
        cv.put(KEY_NAME, name);
        cv.put(KEY_GRADE, grade);
        return getWritableDatabase().insert(TABLE_NAME, null, cv);
    }

    public Cursor getAllRows() {
        return getReadableDatabase().
                rawQuery("SELECT * FROM " + TABLE_NAME, null);
    }
}

对于 CursorAdapter,传递给 onItemClick 的第 4 个参数 long l 是 id(即根据游标的 _id)。

所以就这样 listItemIntent.putExtra("_ID",l);

例如:-

        lvStudents.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent listItemIntent = new Intent(getApplicationContext(), ListItemActivity.class);
                listItemIntent.putExtra("_ID",l); // ID as per _id in the cursor.  
                startActivity(listItemIntent);
            }
        });

评论后编辑:-

Thanks, and for the sake of the question - how to get any other text-view text from the specific list item, in the onItemClick? will view.findViewById(id_of_the_text_box) will get me the correct text?

是的,如果您想从单击的项目访问视图,请使用(假设 TextView,其他适合该视图的内容):-

                view.findViewById(R.id.your_view_id).getText().toString;

所以应用这个你可以:-

        lvStudents.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent listItemIntent = new Intent(getApplicationContext(), ListItemActivity.class);
                listItemIntent.putExtra("_ID",l); // ID as per _id in the cursor.  
                listItemIntent.putExtra("_IDFROMVIEW,
                    view.findViewByID(R.id.tv_id).getText().toString();
                startActivity(listItemIntent);
            }
        });

即它在单击项目的视图列表中找到 View(ListView(又名适配器视图)视图列表的特定 subset/branch)。