Android 使用意图删除ListView中的项

Android 使用意图删除ListView中的项,android,sqlite,listview,android-intent,Android,Sqlite,Listview,Android Intent,我的问题是,我试图从ListView中删除项目,为此,我在CustomAdapter中有一个按钮 Im将此按钮设置为onClickListener,并尝试使用Intent将项目名称传递给主活动 主要是当收到名为“deleteProduct”的意图时,调用方法deleteProduct,在这个方法中,我试图向数据库传递一个要删除的产品名称 我的自定义适配器: private DbItemDeleteListener deleteListener; CustomAdapter(Context co

我的问题是,我试图从ListView中删除项目,为此,我在CustomAdapter中有一个按钮

Im将此按钮设置为onClickListener,并尝试使用Intent将项目名称传递给主活动

主要是当收到名为“deleteProduct”的意图时,调用方法deleteProduct,在这个方法中,我试图向数据库传递一个要删除的产品名称

我的自定义适配器:

private DbItemDeleteListener deleteListener;

CustomAdapter(Context context, ArrayList<Product> productNames,DbItemDeleteListener deleteListener) {
    super(context,R.layout.custom_list_row ,productNames);
    this.deleteListener = deleteListener;
}
 final Product singleProduct=getItem(position);
    final TextView productName=(TextView)customView.findViewById(R.id.ProductName);
    final Button CheckButton = (Button)customView.findViewById(R.id.CheckButton);
    final Button DeleteButton = (Button)customView.findViewById(R.id.DeleteButton);
 DeleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               String product=singleProduct.get_productname();
                deleteListener.delete(product);
            }
        });
当我点击删除按钮时,我也会在logcat中看到这条消息:

 Process: com.example.olev.shoppinglist, PID: 1836
    java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.olev.shoppinglist.DbItemDeleteListener.delete(java.lang.String)' on a null object reference
            at com.example.olev.shoppinglist.CustomAdapter$3.onClick(CustomAdapter.java:80)
            at android.view.View.performClick(View.java:4756)

您不应该只需要使用意图来删除列表项。相反,使用观察者模式。首先,创建一个接口:

public interface DbItemDeleteListener{
    public void delete(String productId);
}
在您的活动中实现接口(您的活动可能不是最适合实现的地方,但因为您已经在这里执行删除操作,所以我将坚持执行该操作):

然后,将实现侦听器的类的实例传递给适配器的构造函数:

public CustomAdapter extends WhateverAdapter{
    private DbItemDeleteListener deleteListener;

    public MyAdapter(DbItemDeleteListener deleteListener){
        this.deleteListener = listener;
    }
}
确保在创建适配器时使用此版本的构造函数

然后,代替onClickListener发送意图:

DeleteButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //get the product name and use the listener to delete

        ...

        deleteListener.delete(productId);
        notifyDataSetChanged();            
    }
}
但如果出于某种原因,您仍然计划使用意图:

对于在其包中将launchMode设置为“singleTop”的活动,或者如果客户端在调用startActivity(Intent)时使用了标志_ACTIVITY _SINGLE _TOP标志,则会调用此函数

我猜现在发生的不是获取主活动的当前实例,而是创建一个新实例。因此,您应该改为在onCreate()中执行相同的签入操作

因此,您可以将活动的启动模式设置为调用onNewIntent的模式:

<activity
    android:launchMode="singleTop"
    ...>
    ....
</activity>
或者,可能更简单,您可以将delete调用移动到onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {

    ... //other onCreate() stuff

    if(getIntent() != null && getIntent().hasExtra("deleteProduct")){
        if (intent.getStringExtra("deleteProduct").equals("deleteProduct")) {
            deleteProduct();
        }
    }
}
此外,您还应该检查

intent.getStringExtra("deleteProduct").equals("deleteProduct")

与示例代码中的“.equals”(“deleteProcust”)不同,但我认为这是一个输入错误。

那么有没有更简单的方法来实现这一点呢?我用一个建议更新了我的答案。如果仍然不清楚,请告诉我。我想在创建适配器(“myAdapter=new CustomAdapter(context,productNames))时,您可能仍在使用旧的构造函数而不是“myAdapter=newcustomadapter(context,productNames,this)”,尽管我没有看到任何这样做的代码。我知道我在回答中没有提到这一点,所以我会加上它。太好了!2个更改:在getProductsFromDb()中,将其作为第一行插入:“productnames.clear();”。另外,在数据库处理程序的deleteProduct()中,您应该像下面这样使用delete:“public void deleteProduct(String productname){SQLiteDatabase DB=getWritableDatabase();String[]args={productname};DB.delete(TABLE_PRODUCTS,COLUMN_productname+“=?”,args);}”确定。只需在活动的delete()方法中构建对话框,并仅在用户确认后调用dbhandler.deleteProduct()和getProductsFromDB()。为什么不直接单击listview上的“删除”按钮?因为按钮是使用CustomAdapter创建的。
<activity
    android:launchMode="singleTop"
    ...>
    ....
</activity>
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
@Override
protected void onCreate(Bundle savedInstanceState) {

    ... //other onCreate() stuff

    if(getIntent() != null && getIntent().hasExtra("deleteProduct")){
        if (intent.getStringExtra("deleteProduct").equals("deleteProduct")) {
            deleteProduct();
        }
    }
}
intent.getStringExtra("deleteProduct").equals("deleteProduct")