使用与其关联的 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。

例如:https://github.com/rodoggx/w4d1_Simple_CursorAdapter/blob/master/app/src/main/java/com/example/sqlitecursoradapter/CustomAdapter.java

替换为:

help.deleteRecordWithId(position);

与:

CustomAdapter.this.remove(CustomAdapter.this.getItem(position));
CustomAdapter.this.notifyDataSetChanged();

它将从您的适配器中删除数据,并且 notifydatasetchanged 将相应地更新您的列表视图。

ListView 没有提供一种直接的方法来对项目内的视图执行操作。请改用 RecyclerView,它比列表视图更可定制且性能更好。

Create Lists and Cards - Android Developer