首页 > 解决方案 > 单击 ListView 中的项目时,从数据库中获取项目的 ID

问题描述

我是 android 新手,在我的应用程序中,当我单击 listview 项目时,我需要从数据库中获取 id,并且我使用此 id 在第二个活动中从数据库中检索数据。但我无法从 listview 获取 id(Listview 在主活动中)

我的 MainActivity - 在我的数据库中的列表视图中显示数据

public class test extends AppCompatActivity {
ImageButton btnadd;
SQLiteDatabase sqLiteDatabase;
DatabaseOpenHelper databaseHelper;
TextView yekuntxt;
    private ListView listView;

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

        this.listView = (ListView) findViewById(R.id.listView);
        DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
        databaseAccess.open();
        final List<String> costumer_data = databaseAccess.getData();
        databaseAccess.close();
        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, costumer_data);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
                {
                   View view = getLayoutInflater().inflate(R.layout.arrayadapter,null);

                    String Id = listView.getItemAtPosition(position).toString();
                    Intent i =new Intent(test.this, activity_daxilet.class);
                    i.putExtra("ID", position);
                    startActivity(i);

                }

            }
        });

我的数据库访问

public class DatabaseAccess {
private SQLiteOpenHelper openHelper;
private SQLiteDatabase database;
private static DatabaseAccess instance;

private DatabaseAccess(Context context) {
    this.openHelper = new DatabaseOpenHelper(context);
}

public static DatabaseAccess getInstance(Context context) {
    if (instance == null) {
        instance = new DatabaseAccess(context);
    }
    return instance;
}
public void open() {
    this.database = openHelper.getWritableDatabase();
}
public void close() {
    if (database != null) {
        this.database.close();
    }
}

public List<String> getData() {
    List<String> list = new ArrayList<>();
    Cursor cursor = database.rawQuery("SELECT AD,SOYAD FROM costumer_data", null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {

        list.add(cursor.getString(0)+ " " + cursor.getString(1));

        cursor.moveToNext();
    }
    cursor.close();
    return list;

我的第二个活动

public class activity_daxilet extends AppCompatActivity {
TextView ad,medaxil,mexaric;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_daxilet);



    Bundle bundle = getIntent().getExtras();
    if (bundle !=null){
        ad.setText("@position");
    }

}

标签: javaandroidsqlite

解决方案


使用 ListAdapter 的第三个参数位置将不等同于 id,尤其是在行已被删除的情况下。

最简单的方法是使用游标适配器,在这种情况下,id 将是传递给onItemClickListener. SimpleCursorAdapter可能就足够了。

要转换为使用 SimpleCursorAdapter,然后:-

  1. 向您的 DatabaseAccess.java 添加一个方法以返回一个 Cursor(或替换 getData 方法),例如

:-

public Cursor getDataAsCursor() {
    String[] columns = new String[]{"AD","SOYAD","rowid AS " + BaseColumns._ID};
    return this.database.query(
            "costumer_data",
            columns,
            null,null,null,null,null
    );
}
  • 请注意,不清楚您是否定义了 id 列或它的名称。游标适配器需要一个名为_id的列,BaseColumns._ID解析为_id,因此使用上述方法。
    • 已使用查询便捷方法而不是 rawQuery 方法,尽管它可能看起来更复杂,但建议使用 rawQuery。

.

  1. FOR TESTING 向 DatabaseAccess.java 添加一个方法允许添加数据

:-

public long addRow(String ad, String soyad) {
    ContentValues cv = new ContentValues();
    cv.put("AD",ad);
    cv.put("SOYAD",soyad);
    return this.database.insert("costumer_data",null,cv);
}
  • 请注意,如果您已经有数据或有等效方法,则可能不需要

.

  1. 修改MainActivity

:-

public class test extends AppCompatActivity {
    ImageButton btnadd; //??
    SQLiteDatabase sqLiteDatabase; // NOT NEEDED
    DatabaseOpenHelper databaseHelper; // NOT NEEDED
    TextView yekuntxt; //??
    private ListView listView;
    SimpleCursorAdapter adapter; // ADDED
    Cursor cursor; // ADDED
    DatabaseAccess databaseAccess; // ADDED

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

        this.listView = (ListView) findViewById(R.id.listView);
        databaseAccess = DatabaseAccess.getInstance(this); // Changed to use class variable
        databaseAccess.open();
        addSomeData(); // <<<< ADDED for testing (adds some data to the table (4 rows as below))
        cursor = databaseAccess.getDataAsCursor(); // ADDED
        //final List<String> costumer_data = databaseAccess.getData(); // REMOVED
        //databaseAccess.close(); // <<<<<<<<<< MUST NOT CLOSE DB WHEN using Cursor (see onDestory method)
        adapter = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_2, // (show AD and SOYAD seprately)
                cursor, //<<<< The cursor used for the source data of the ListView
                new String[]{"AD","SOYAD"}, // The columns FROM which to get the data
                new int[]{android.R.id.text1, // The respective views TO which the data is placed
                        android.R.id.text2},
                0
        );
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
                {
                    Intent i = new Intent(test.this, activity_daxilet.class);
                    i.putExtra("ID", id);
                    startActivity(i);
                }
            }
        });
    }

    //<<<<<<<<<< Added to close the Cursor  and then database when done with it
    @Override
    protected void onDestroy() {
        cursor.close();
        databaseAccess.close();
        super.onDestroy();
    }

    //<<<<<<<<<< Added to load some data for testing
    private void addSomeData() {
        databaseAccess.addRow("TestAD1","TestSOYAD1");
        databaseAccess.addRow("TestAD2","TestSOYAD2");
        databaseAccess.addRow("TestAD3","TestSOYAD3");
        databaseAccess.addRow("TestAD4","TestSOYAD4");
    }
}
  • 评论应解释所做的更改

.

  1. 修改activity_daxilet.java获取传递的id

:-

public class activity_daxilet extends AppCompatActivity {

    TextView showpassedid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_daxilet);
        showpassedid = (TextView) this.findViewById(R.id.showpassedid);

        long passedid = this.getIntent().getLongExtra("ID",-1);
        showpassedid.setText("Id Passed was " + String.valueOf(passedid));
    }
}
  1. 修改 activity_daxilet.xml 以包含 TextView showpassedid

例如:-

<?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=".activity_daxilet">
    <TextView
        android:id="@+id/showpassedid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

结果

首次运行时:-

在此处输入图像描述

点击一个项目 (3) :-

在此处输入图像描述


推荐阅读