Android 使用意图删除ListView中的项
我的问题是,我试图从ListView中删除项目,为此,我在CustomAdapter中有一个按钮 Im将此按钮设置为onClickListener,并尝试使用Intent将项目名称传递给主活动 主要是当收到名为“deleteProduct”的意图时,调用方法deleteProduct,在这个方法中,我试图向数据库传递一个要删除的产品名称 我的自定义适配器: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
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")