【问题标题】:listview onClick return wrong resultlistview onClick 返回错误结果
【发布时间】:2026-02-15 12:05:02
【问题描述】:

我有来自 SQLite 数据库的数据的自定义列表视图。我可以添加和编辑项目。我也有 SearchVIew 在工具栏中按名称搜索项目。

问题是当我想编辑项目并使用 SearchView 找到它时,onClick 方法返回错误的 id(列表中第一个项目)。 如果我不使用搜索,那么一切都很好。例如:

我的班级代码:

public class ProductCategoryActivity extends AppCompatActivity {

private ListView myProductsList;
private DataBaseHelper dataBaseHelper;
private SQLiteDatabase db;
private Cursor productCursor;
private ArrayList<Product> productList;
private int tableId;
private String dbName;

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    Intent idOfGroup = new Intent(getIntent());
    tableId = idOfGroup.getIntExtra("table_id", 0);

    myProductsList = (ListView) findViewById(R.id.lvMyProducts);

    switch (tableId) {
        case 1:
            dbName = DataBaseHelper.TABLE_MY_PRODUCTS;
            break;
    }

    //allow adding and editing products if tableId == 1
    if (tableId == 1) {
        myProductsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //get id by click on list view item
                String sql = "SELECT " + DataBaseHelper.COLUMN_ID + "  FROM " + dbName;
                productCursor = db.rawQuery(sql, null);
                ArrayList<Long> arrayList = new ArrayList<>();
                if (productCursor.moveToFirst()) {
                    do {
                        arrayList.add(Long.parseLong(productCursor.getString(0)));
                    } while (productCursor.moveToNext());
                } else {
                    throw new NullPointerException();
                }
                //sending id to another activity
                Intent intent = new Intent(ProductCategoryActivity.this, ProductAddEditActivity.class);
                intent.putExtra("id", arrayList.get(position));
                startActivity(intent);
            }
        });
    }
    dataBaseHelper = new DataBaseHelper(getApplicationContext());
    //creating db
    dataBaseHelper.create_db();

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.newProduct:
            Intent intent = new Intent(ProductCategoryActivity.this, ProductAddEditActivity.class);
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

@Override
public void onResume() {
    super.onResume();
    productList = new ArrayList<>();
    productList.clear();
    db = dataBaseHelper.open();
    //get data from db
    productCursor = db.rawQuery("select * from " + dbName, null);
    setProduct();
}


//product search by name
public Cursor getProductListByKeyword(String search) {
    productList = new ArrayList<>();
    productList.clear();
    db = dataBaseHelper.open();
    //get data from db by word
    productCursor = db.rawQuery("SELECT * FROM " + dbName + " WHERE "
            + DataBaseHelper.COLUMN_NAME + "  LIKE  '%" + search + "%' ", null);
    setProduct();
    return productCursor;
}

private void setProduct() {
    //select  required columns
    if (productCursor != null && productCursor.getCount() != 0) {
        if (productCursor.moveToFirst()) {
            do {
                Product product = new Product();
                product.setProductName(productCursor.getString(productCursor.getColumnIndex(DataBaseHelper.COLUMN_NAME)));

                productList.add(product);
            } while (productCursor.moveToNext());
        }
    }
    productCursor.close();
    ProductListAdapter productListAdapter = new ProductListAdapter(this, productList);
    myProductsList.setAdapter(productListAdapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    //the add button is hidden if tableId != 1
    if (tableId != 1) {
        MenuItem menuItem = menu.findItem(R.id.newProduct);
        menuItem.setVisible(false);
    }
    SearchView searchView = (SearchView) menu.findItem(R.id.searchForSee).getActionView();
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String s) {
            productCursor = getProductListByKeyword(s);
            Toast.makeText(ProductCategoryActivity.this, productCursor.getCount() + " " +
                            getString(R.string.txt_products_found),
                    Toast.LENGTH_LONG)
                    .show();
            return false;
        }
        @Override
        public boolean onQueryTextChange(String s) {
            productCursor = getProductListByKeyword(s);
            return false;
        }
    });
    return true;

}
@Override
public void onDestroy() {
    super.onDestroy();
    db.close();
    productCursor.close();
}

【问题讨论】:

  • 我不懂你(长id???)
  • 这对我有什么帮助?
  • @pskink 但长 id 返回 listview 项 id,但我需要 SQLite 行的 id,它们不是同一个 id
  • 但我使用自定义适配器

标签: android sqlite listview search


【解决方案1】:

我在 onClick 方法中解决了我的问题:

 myProductsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //get id by click on list view item
                long productId;
                if (productCursor.moveToPosition(position)) {
                    productId = Long.parseLong(productCursor.getString(0));
                } else {
                    throw new NullPointerException();
                }
                //sending id to another activity
                Intent intent = new Intent(ProductCategoryActivity.this, ProductAddEditActivity.class);
                intent.putExtra("id", productId);
                startActivity(intent);
            }
        });

【讨论】:

    【解决方案2】:

    我认为您的问题是如何获得该 ID。您首先从表中获取所有列 ID,然后创建一个 ID 数组,然后根据位置从那里选择一个条目。

    无论您的搜索结果如何,您的 arrayList 变量都将始终包含表中的所有 ID。所以当你访问arrayList.get(position)时,它会返回表中那个位置上的对象,而不是列表中。

    您应该使用 long id 或更改您的 SQL 查询,以便您只获得在 SQL 结果中符合您的搜索测试的条目。

    可能是这样的

    String sql = "SELECT " + DataBaseHelper.COLUMN_ID + "  FROM " + dbName + " WHERE " + DataBaseHelper.COLUMN_NAME + "=" + searchText;
    

    相应地更改变量。

    比这更简单,您可以简单地使用参数中传递的long id

    【讨论】:

    • 甚至比getItemId 更简单:long id 作为最后一个参数传递给onItemClick 方法
    • 是的。这是正确的。但我不确定 OP 是否正确实现了 getItemId 函数。 @Andrii,如果您在列表适配器中正确实现了此功能,则可以简单地使用long id 传入参数。
    • SimpleCursorAdapter(或一般CursorAdapter)已经实现了所有这些东西 - 无需重新发明*
    • 我明白了。不知道。 :P
    • ` 意图意图 = new Intent(ProductCategoryActivity.this, ProductAddEditActivity.class); intent.putExtra("id", id); startActivity(intent);` 不起作用,因为在另一个活动中我得到这样的数据:光标 productCursor = db.rawQuery("select * from " + DataBaseHelper.TABLE_MY_PRODUCTS + " where " + DataBaseHelper.COLUMN_ID + " = ?", new String[]{String.valueOf(extras.getLong("id"))});