使用与其关联的 Button 从 ListView 中删除一行
Deleting a row from a ListView using Button associated with it
我有一个列表视图,我在上面显示我的数据库中的数据,现在我想根据与每一行相关联的按钮单击来删除行。
每当我按下“完成”按钮时,CustomAdapter class 都会出现异常。
CursorAdapter 代码是这样的:
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
del.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
help.deleteRecordWithId(position);
}
}
);
return super.getView(position, convertView, parent);
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
}
}
我的数据库函数 deleteRecordWithId() 是:
public boolean deleteRecordWithId(int id) {
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
我遇到了这个异常:
java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.View.findViewById(int)' on a null object
reference
这段代码有什么问题。请帮我改正一下。
将setOnItemClickListener
设置为您的列表视图...
yourListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
yourListView.remove(position);
database.removeItem(id);//create removemethod in database class
}
});
定义 removeItem 方法
public void remove(long id){
String str =String.valueOf(id);
database.execSQL("DELETE FROM <TABLE_NAME> WHERE _id = '" + str + "'");
}
第一种方法:你这样描述
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
}}
主要活动:
public class MainActivity{
private CustomAdapter cursorAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cursorAdapter = new CustomAdapter(this, null);
}
public void deleteRecordWithId(View view) {
View parentRow = (View) view.getParent().getParent();
ListView listView = (ListView) view.getParent().getParent().getParent();
int position = listView.getPositionForView(parentRow);
long id = cursorAdapter.getItemId(position);
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
}
和xml这样的:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/task_outer_container"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:background="@drawable/background_transparent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:id="@+id/delete_button"
android:onClick="deleteRecordWithId"
app:srcCompat="@drawable/remove_icon"
android:background="@drawable/background_transparent"
android:layout_gravity="center_vertical"
android:adjustViewBounds="false"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:layout_marginEnd="-5dp"/>
</RelativeLayout>
第二种方法:您不应该在 Cursoradapter 中使用 getView。您需要在绑定视图中完成所有操作。所以你无法通过getview访问到id。
替换为:
help.deleteRecordWithId(position);
与:
CustomAdapter.this.remove(CustomAdapter.this.getItem(position));
CustomAdapter.this.notifyDataSetChanged();
它将从您的适配器中删除数据,并且 notifydatasetchanged 将相应地更新您的列表视图。
ListView 没有提供一种直接的方法来对项目内的视图执行操作。请改用 RecyclerView,它比列表视图更可定制且性能更好。
我有一个列表视图,我在上面显示我的数据库中的数据,现在我想根据与每一行相关联的按钮单击来删除行。
每当我按下“完成”按钮时,CustomAdapter class 都会出现异常。 CursorAdapter 代码是这样的:
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
del.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
help.deleteRecordWithId(position);
}
}
);
return super.getView(position, convertView, parent);
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
}
}
我的数据库函数 deleteRecordWithId() 是:
public boolean deleteRecordWithId(int id) {
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
我遇到了这个异常:
java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.View.findViewById(int)' on a null object
reference
这段代码有什么问题。请帮我改正一下。
将setOnItemClickListener
设置为您的列表视图...
yourListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
yourListView.remove(position);
database.removeItem(id);//create removemethod in database class
}
});
定义 removeItem 方法
public void remove(long id){
String str =String.valueOf(id);
database.execSQL("DELETE FROM <TABLE_NAME> WHERE _id = '" + str + "'");
}
第一种方法:你这样描述
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
}}
主要活动:
public class MainActivity{
private CustomAdapter cursorAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cursorAdapter = new CustomAdapter(this, null);
}
public void deleteRecordWithId(View view) {
View parentRow = (View) view.getParent().getParent();
ListView listView = (ListView) view.getParent().getParent().getParent();
int position = listView.getPositionForView(parentRow);
long id = cursorAdapter.getItemId(position);
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
}
和xml这样的:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/task_outer_container"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:background="@drawable/background_transparent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:id="@+id/delete_button"
android:onClick="deleteRecordWithId"
app:srcCompat="@drawable/remove_icon"
android:background="@drawable/background_transparent"
android:layout_gravity="center_vertical"
android:adjustViewBounds="false"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:layout_marginEnd="-5dp"/>
</RelativeLayout>
第二种方法:您不应该在 Cursoradapter 中使用 getView。您需要在绑定视图中完成所有操作。所以你无法通过getview访问到id。
替换为:
help.deleteRecordWithId(position);
与:
CustomAdapter.this.remove(CustomAdapter.this.getItem(position));
CustomAdapter.this.notifyDataSetChanged();
它将从您的适配器中删除数据,并且 notifydatasetchanged 将相应地更新您的列表视图。
ListView 没有提供一种直接的方法来对项目内的视图执行操作。请改用 RecyclerView,它比列表视图更可定制且性能更好。