使用与其关联的Button从ListView中删除行

时间:2017-11-03 06:57:20

标签: android listview nullpointerexception android-cursoradapter

我有一个listview,我在其中显示数据库中的数据,现在我想根据点击的按钮删除行,该按钮与每行相关联。

每当我按完成按钮时,我在CustomAdapter类中都有异常。 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

此代码有什么问题。请帮我纠正。

4 个答案:

答案 0 :(得分:1)

替换它:

help.deleteRecordWithId(position);

使用:

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

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

答案 1 :(得分:0)

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 + "'");
    }

答案 2 :(得分:0)

第一种方法:你这样描述

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

MainActivity:

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。您需要在bindview中执行所有操作。所以你用getview无法达到id。

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

答案 3 :(得分:0)

ListView没有提供一种直接的方法来实现对项目内部视图的操作。相反,使用RecyclerView,它比列表视图更具可定制性和性能。

Create Lists and Cards - Android Developer