使用意图删除 ListView 中的项目

Deleting items in ListView using intent

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

我正在将此按钮设置为 onClickListener 并尝试使用 Intent 将项目名称传递给主 activity。

在 Main 中,当收到名为 "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);
            }
        });

我的主要:

DbItemDeleteListener deleteListener;
ArrayAdapter<Product> adapter;
ArrayList<Product> productnames=new ArrayList<>();
DBHandler dbhandler;
 @Override
public void delete(String productId){
    dbhandler.deleteProduct(productId);
}

还有我的 DBHandler:

  public void deleteProduct(String productname){
    SQLiteDatabase db=getWritableDatabase();
    db.execSQL("DELETE FROM " +TABLE_PRODUCTS+ " WHERE "+ COLUMN_PRODUCTNAME+ "=\" "+ productname +"\";");
    }

当我单击删除按钮时,我也在 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.onClick(CustomAdapter.java:80)
            at android.view.View.performClick(View.java:4756)

您真的不需要仅使用 Intent 来删除列表项。相反,使用观察者模式。首先,创建一个接口:

public interface DbItemDeleteListener{
    public void delete(String productId);
}

在您的 Activity 中实现接口(您的 activity 可能不是实现的最佳位置,但因为它是您已经在进行删除的地方,所以我会坚持下去) :

public class MyActivity extends Activity implements DbItemDeleteListener{

    ...

    @Override
    public void delete(String productId){
        dbhandler.deleteProduct(productId);
    }
}

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

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();            
    }
}

但如果您出于某种原因仍计划使用 Intent:

http://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent)

This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent).

我猜测正在发生的事情是,您实际上不是在获取 Main activity 的当前实例,而是在创建一个新实例。因此,您应该在 onCreate() 中进行相同的检查。

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

<activity
    android:launchMode="singleTop"
    ...>
    ....
</activity>

and/or 也将标志添加到您的意图中:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

或者,也许更简单,您可以将删除调用移至 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"),但我认为这是一个错字。