【问题标题】:Android : deleting an item from listview causes not assigning idAndroid:从列表视图中删除项目导致不分配 id
【发布时间】:2015-02-10 22:00:13
【问题描述】:

如果我从我的列表视图中删除一个项目,除了最后一条记录,其他记录 id 不会改变。 (是的,在这种情况下,我不应该知道)。我会用这个场景来解释 假设我在列表视图中添加了 3 个项目,删除第二个项目后,第三个项目的 id 不会将其 id 更改为 2,即使在我的查询中使用 Autoincrement 后也是如此。所以如果我点击第三个项目。它会导致应用程序崩溃并在日志中显示光标索引超出范围异常

下面是我的相关代码

DBhelper.java

public class DBhelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "MyDBname.db";
public static final String DATABASE_VERSION = "1";
public static final String PRODUCTS_TABLE_NAME= "products";
public static final String PRODUCTS_COLUMN_ID= "id";
public static final String PRODUCTS_COLUMN_NAME= "name";
public static final String PRODUCTS_COLUMN_QUAN= "quant";
public static final String PRODUCTS_COLUMN_PRICE= "price";



public DBhelper(Context context) 
    {
    super(context, DATABASE_NAME, null, 1);
    // TODO Auto-generated constructor stub

    }



@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub

    db.execSQL("create table products " + "(id INTEGER PRIMARY KEY AUTOINCREMENT,name text,quant text,price text)");
    //db.execSQL(  "create table contacts " + "(id integer primary key, name text,phone text,email text, street text,place text)");

}



@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
    db.execSQL("DROP TABLE IF EXISTS    products");
    onCreate(db);
}

public boolean insertProduct(String name,String quant,String price)
{

    SQLiteDatabase db =this.getWritableDatabase();
    ContentValues contentvalues =new ContentValues();
    contentvalues.put("name", name);
    contentvalues.put("price", price);
    contentvalues.put("quant", quant);

    db.insert("products", null, contentvalues);
    return true;

}

public Cursor getData(int id)
{
    SQLiteDatabase db= this.getReadableDatabase();

    Cursor res = db.rawQuery("select * from products where id="+id+"", null);

    return res;

}

public int numberofRows(){
    SQLiteDatabase db = this.getReadableDatabase();
    int numrows = (int) DatabaseUtils.queryNumEntries(db, PRODUCTS_COLUMN_NAME );
    return numrows;

}

public boolean updateProducts(Integer id,String name, String price,String quant){
    SQLiteDatabase db=this.getWritableDatabase();
    ContentValues contentvalues = new ContentValues();
    contentvalues.put("name",name);
    contentvalues.put("quant", quant);
    contentvalues.put("price", price);
    db.update("products", contentvalues, "id=?", new String[]{ Integer.toString(id)});

    return true;

}

public Integer deleteproduct(Integer id)
{
    SQLiteDatabase db=this.getWritableDatabase();
    Cursor res= db.rawQuery("select * from products", null);
    res.moveToFirst();
    return db.delete("products", "id=?", new String[] {Integer.toString(id)});
}

public ArrayList<String> getallProducts(){

    ArrayList<String> arraylist = new ArrayList<String>();
    SQLiteDatabase db= this.getReadableDatabase();
    Cursor res= db.rawQuery("select * from products", null);
    res.moveToFirst();
    while(res.isAfterLast()==false)
    {
        arraylist.add(res.getString(res.getColumnIndex(PRODUCTS_COLUMN_NAME)));
        res.moveToNext();

    }

return arraylist;

}

}

下面的类是为了显示列表

Mainproducts.java

public class MainProducts extends Activity {

private ListView lv;
DBhelper mydb;
//Button btn1;Intent i;

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

    mydb = new DBhelper(this);
    ArrayList<?> arrayList =mydb.getallProducts();

    @SuppressWarnings("unchecked")
    ArrayAdapter adp =new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
    lv = (ListView)findViewById(R.id.listView1);
    lv.setAdapter(adp);


    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stu
            //Toast.makeText(getApplicationContext(), ""+arg2, Toast.LENGTH_SHORT).show();
            int idtosearch =arg2+1;
            Bundle databundle= new Bundle();
            databundle.putInt("id",idtosearch);
            Intent intent = new Intent(MainProducts.this,AddActivity.class);
            intent.putExtras(databundle);
            startActivity(intent);

        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.add, menu);
    return true;
}

 public boolean onOptionsItemSelected(MenuItem item) 
   { 
      super.onOptionsItemSelected(item); 
      switch(item.getItemId()) 
      { 
         case R.id.add1: 
            Bundle extras = new Bundle();
            Toast.makeText(getApplicationContext(), "ID "+extras.getInt("id"), Toast.LENGTH_SHORT).show();
            extras.putInt("id", 0);
            Intent intent = new Intent(MainProducts.this,com.example.products2.AddActivity.class);
            intent.putExtras(extras);
            startActivity(intent);
            return true; 
         default: 
            return super.onOptionsItemSelected(item); 

       } 

   } 

}

这个类显示添加和编辑项目 , AddActivity.java

public class AddActivity extends Activity {

int idtoupdate=0;
private DBhelper mydb;
TextView name;
TextView quant;
TextView price;
Button btn1;

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

    name = (TextView) findViewById(R.id.editTextname);
    quant = (TextView) findViewById(R.id.editTextquant);
    price = (TextView)findViewById(R.id.editTextprice);
    btn1=(Button)findViewById(R.id.button1);
    mydb =new DBhelper(this);



    Bundle extras =getIntent().getExtras();
    if(extras!=null) 
    {
        int Value=extras.getInt("id");
         if(Value>0)
         {
        Cursor rs=mydb.getData(Value);
        Toast.makeText(getApplicationContext(), "Val "+Value, Toast.LENGTH_SHORT).show();
        idtoupdate=Value;
        rs.moveToFirst();
        String nam =  rs.getString(rs.getColumnIndex(DBhelper.PRODUCTS_COLUMN_NAME));
        String quan = rs.getString(rs.getColumnIndex(DBhelper.PRODUCTS_COLUMN_QUAN));
        String pric = rs.getString(rs.getColumnIndex(DBhelper.PRODUCTS_COLUMN_PRICE));

         if (!rs.isClosed()) 
            {
               rs.close();
            }   

         //Button b =(Button) findViewById(R.id.button1);
         btn1.setVisibility(View.INVISIBLE);

         name.setText((CharSequence)nam);
         //name.setEnabled(true);
         name.setFocusable(false);
         name.setClickable(false);

         quant.setText((CharSequence)quan);
         //quant.setEnabled(true);
         quant.setFocusable(false);
         quant.setClickable(false);

         price.setText((CharSequence)pric);
         //quant.setEnabled(true);
         price.setFocusable(false);
         price.setClickable(false);


    }    


    }   
    }






@Override
public boolean onCreateOptionsMenu(Menu menu) {
     Bundle extras = getIntent().getExtras(); 
      if(extras !=null)
      {
         int Value = extras.getInt("id");
        if(Value>0){
            getMenuInflater().inflate(R.menu.addproducts, menu);
         }
        else{
          getMenuInflater().inflate(R.menu.main, menu);
         }
      }
      return true;
}

public boolean onOptionsItemSelected(MenuItem item)
{
    super.onOptionsItemSelected(item);
    switch(item.getItemId())
    {
        case R.id.item1:
            Button b= (Button) findViewById(R.id.button1);
            b.setVisibility(View.VISIBLE);
              name.setEnabled(true);
              name.setFocusableInTouchMode(true);
              name.setClickable(true);

              quant.setEnabled(true);
              quant.setFocusableInTouchMode(true);
              quant.setClickable(true);

              price.setEnabled(true);
              price.setFocusableInTouchMode(true);
              price.setClickable(true);

              return true;
        case R.id.item2:
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.deleteProduct)
            .setPositiveButton(R.string.yes,new  DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int id) {
                    // TODO Auto-generated method stub
                    mydb.deleteproduct(idtoupdate);
                    Toast.makeText(getApplicationContext(), "Deleted Successfully", Toast.LENGTH_LONG).show();
                    Intent i= new Intent(AddActivity.this,MainProducts.class);
                    startActivity(i);
                }
            })
            .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int id) {
                    // TODO Auto-generated method stub

                }
            });
            AlertDialog d= builder.create();
            d.setTitle("Are you sure?");
            d.show();
            return true;
              default: 
              return super.onOptionsItemSelected(item);
    }



}



public void run(View view)
  { 
Bundle extras = getIntent().getExtras();
if(extras !=null)
{int Value = extras.getInt("id");

  if(Value>0){

     if(mydb.updateProducts(idtoupdate,name.getText().toString(), price.getText().toString(), quant.getText().toString())){
        Toast.makeText(getApplicationContext(), "Updated", Toast.LENGTH_SHORT).show();  
        Intent intent = new Intent(AddActivity.this,com.example.products2.MainProducts.class);
        startActivity(intent);
      }     
     else{
        Toast.makeText(getApplicationContext(), "not Updated", Toast.LENGTH_SHORT).show();  
     }
     }
  else{

     if(mydb.insertProduct(name.getText().toString(), price.getText().toString(), quant.getText().toString())){
        Toast.makeText(getApplicationContext(), "done", Toast.LENGTH_SHORT).show(); 
     }      
     else{
        Toast.makeText(getApplicationContext(), "not done", Toast.LENGTH_SHORT).show(); 
     }
     Intent intent = new Intent(AddActivity.this,com.example.products2.MainProducts.class);
     startActivity(intent);
     }


}
}

}

请帮助我在互联网上没有找到任何关于相同的帮助。提前致谢,这是我的第一个问题,如果我犯了任何错误,请在必要时更正。

【问题讨论】:

  • 为什么会改变?
  • 如果第 3 项在删除第 2 项后将其位置从 3 更改为 2。那么第三个项目也应该改变它的位置。所以当我创建一个新的行/项目时,第三个位置 id 将被赋予。
  • 为什么要这样做?身份证不是职位。根据定义,ID 不会改变。
  • 好吧,我承认第 3 项将占据第 2 项的位置,但不会更改其 ID。那为什么当我点击最后一项时它会崩溃我的应用程序.. N 显示我描述的异常
  • Idk,如果您假设 ID 是职位,那么这可能就是原因。

标签: java android sqlite listview android-listview


【解决方案1】:

使用integer primary keyinteger primary key autoincrement 不会对其曾经分配给行的id 进行任何更改。

在您的代码中,您尝试通过获取 listView 的位置来删除数据库项目,这只会从 listView 中正确删除第一个项目,然后它可能会显示错误。

AlertDialog.Builder.setPositiveButton方法中放入这段代码。

Bundle extras =getIntent().getExtras();
int Value=extras.getInt("id");

MainProducts mProduct = new MainProducts();

HashMap<String, Object> obj = (HashMap<String, Object>) mProducts.adp.getItem(position);
final String prodId = (String)obj.get("id");  //here you are getting actual id of item from database

//now delete the item from database
mydb.deleteproduct(Integer.parseInt(prodId));

【讨论】:

  • 你的意思是我应该在 onClick(DialogInterface dialog, int id) 方法下添加这个 setPositiveButton 。好吧,它现在无法识别 adp 和 position。我修复了你在代码中犯的 mproducts 错误。无论如何,我们不能在DBhelper 类的deleteproducts() 方法下这样做
  • 再次查看我的评论
  • 您能再检查一下我的问题吗?
  • @RonitChanana 发生错误是因为您没有在您的意图附加项中传递实际的数据库项目 ID,您正在传递项目的位置,它并不总是返回正确的数据库项目
  • 我实际上从 minimal reproducible example (tutorialspoint.com/android/android_sqlite_database.htm) 修改了我的项目。但同样的错误是在这引起的。如果您可以在您的系统上运行它,那将非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 2016-11-27
相关资源
最近更新 更多