使用意图删除 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"),但我认为这是一个错字。
我的问题是我试图从 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"),但我认为这是一个错字。