【问题标题】:Deleting last element from listview从列表视图中删除最后一个元素
【发布时间】:2014-11-08 09:14:07
【问题描述】:

好的,所以我正在尝试从 ListView 中删除元素,在我尝试删除最后一个元素之前一切正常,但前提是我删除了倒数第二个元素并尝试删除最后一个元素。这是我的代码:

public class TestActivity extends ListActivity {

ListView list;
PAdapter adapter;
static SQLiteDatabase db;
static ArrayList<Profesor> datos;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

db = openOrCreateDatabase("DBLogin", MODE_PRIVATE, null);
    db.execSQL("CREATE TABLE IF NOT EXISTS Profesor (Id integer primary key AUTOINCREMENT"
            + ", Nombre" + " varchar(30), Imagen varchar(15), Fecha" + " varchar(15)" +
            ", Direccion varchar(35), sexo varchar(10), Telefono varchar(15), creado int);");

    list = (ListView) findViewById(android.R.id.list);

    datos = new ArrayList<Profesor>();

    datos = datos();
    adapter = new PAdapter(this, R.layout.row, datos);

    setListAdapter(adapter);



list.setOnItemLongClickListener(new OnItemLongClickListener(){

        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                int arg2, long arg3) {
            if (datos.get(arg2).getCreado() == 1) {
                PopupMenu popup = new PopupMenu(TestActivity.this, list);
                popup.getMenuInflater().inflate(R.menu.popup3, popup.getMenu());
                final int id = arg2;
                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    public boolean onMenuItemClick(MenuItem item) {
                        delete(datos.get((int)adapter.getItemId(id)));
                        datos = datos();
                        adapter = new PAdapter(TestActivity.this, R.layout.row, datos);
                        setListAdapter(adapter);
                        list.invalidateViews();
                        return true;
                    }
                });

                popup.show();
            }
            return false;
        }
    });
}


private ArrayList<Profesor> datos(){
    ArrayList<Profesor> ap = new ArrayList<Profesor>();
    Cursor cursor = db.rawQuery("SELECT * FROM Profesor", null);
    if(cursor.moveToFirst()){
        do {
            Profesor p = new Profesor(null, null);
            p.setId(cursor.getInt(0));
            p.setNombre(cursor.getString(1));
            p.setFecha(cursor.getString(3));
            p.setDireccion(cursor.getString(4));
            p.setSexo(cursor.getString(5));
            p.setImagen(cursor.getString(2));
            p.setCreado(cursor.getInt(7));
            p.setTelefono(cursor.getString(6));
            ap.add(p);
        } while(cursor.moveToNext());
    }
    return ap;
}

public static void delete(Profesor p){
    db.execSQL("DELETE FROM Profesor WHERE Id = " + p.getId() + ";");
}

这是 PAdapter 类:

public class PAdapter extends ArrayAdapter<Profesor> {

private Context context;
private int layout;
private ArrayList<Profesor> datos;

public PAdapter(Context context, int layout, ArrayList<Profesor> datos) {
    super(context, layout, datos);
    this.context = context;
    this.layout = layout;
    this.datos = datos;
}

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View item = inflater.inflate(layout, parent, false);

    ImageView imagen = (ImageView) item.findViewById(R.id.imageView1);
    datos.get(position).imagen(imagen, context, false);


    TextView nombre = (TextView) item.findViewById(R.id.tNombre);
    nombre.setText(datos.get(position).getNombre());


    return item;
}

}

有趣的是,它执行 delete 之后的代码,但不会删除最后一个元素,也不会抛出异常。再说一次,它只发生在最后一个元素上,只有在我删除它之前的元素之后,如果我关闭并重新打开应用程序,我可以正常删除它。

【问题讨论】:

标签: android sqlite android-listview sql-delete


【解决方案1】:

试试这个:它对我来说很好用。

    ListView list;
    adapter = new MyListAdapter(this);
    list = (ListView) findViewById(android.R.id.list);
    list.setAdapter(adapter);
    list.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> a, View v, int position, long id) {
        AlertDialog.Builder adb=new AlertDialog.Builder(MyActivity.this);
        adb.setTitle("Delete?");
        adb.setMessage("Are you sure you want to delete " + position);
        final int positionToRemove = position;
        adb.setNegativeButton("Cancel", null);
        adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                MyDataObject.remove(positionToRemove);
                adapter.notifyDataSetChanged();
            }});
        adb.show();
        }
    });

【讨论】:

  • 事情是我也需要从数据库中删除它,但它没有这样做,但仅限于最后一个元素,并不总是如此。我希望你们中的任何人都可以帮助我了解我的代码有什么问题。
【解决方案2】:

我假设您将 pos = 3 作为参数值传递。因为list的大小是3,所以最后一个元素的位置应该是2。

*编辑:

记住,listview 和adapter 的起始索引是不同的。 ListView 项 pos 从“1”作为第一个位置开始,适配器(例如数组)从索引“0”作为第一个位置开始。

adapter.remove(adapter.getItem(pos-1)); 

【讨论】:

  • 我很确定项目位置也是从 0 开始的,我使用了类似的代码并且它工作得非常完美,而且它不会删除你选择的元素。我也认为它会给出一个 ArrayIndexOutOfBoundsException 或类似的东西。
【解决方案3】:

您的代码中有一些错误。我的以下建议不保证会解决您当前的问题,但让我们尝试一下:

  1. 注意当你设置适配器setListAdapter(adapter);时,列表将设置它的适配器次用户做了onClick - 这是一种浪费。使用adapter.add()/adapter.remove()而不是一遍又一遍地通过setListAdapter 重置所有数据。
  2. 你打电话给list.invalidateViews(),是为了什么?在您的情况下,adapter.notifyDataSetChanged() 就足够了。

【讨论】:

  • 感谢您的建议,我会记住的。但主要问题是从 de DB 中删除最后一个元素,它仅在某些时候有效,并且与所有其他元素完美配合。
【解决方案4】:

我通过在单个项目的活动中添加它来解决它,所以如果我回到 ListView 活动,它会因为完成()而被刷新;函数。[2020 年 2 月 8 日]

@Override
public void onBackPressed() {
    super.onBackPressed();
    startActivity(new Intent(SingleItem.this, ListView.class));
    finish();
}

【讨论】: