Как удалить конкретный элемент из таблицы в базе данных? - PullRequest
0 голосов
/ 02 июня 2019

Я хочу создать приложение со списком дел, и я хотел удалить элемент в списке, установив флажок.

Я попытался создать «deleteTask» (как вы видите в коде) метод в классе базы данных.Кроме того, вы можете увидеть метод "populateListView", он предоставляет данные из базы данных в просмотр списка, я использую его для обновления после каждого удаления задачи из базы данных.

 public void deleteTask(String task) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_NAME, COL2 , new String[]{task});
    }

 public void populateListView() {
        try {
            mDataBaseHelper = new DataBaseHelper(MainActivity.this);
            data = mDataBaseHelper.getData();
            mArrayList = new ArrayList<>();
            if (data.getCount() != 0) {
                while (data.moveToNext()) {
                    mArrayList.add(data.getString(1));
                    ListAdapter listAdapter = new ArrayAdapter(MainActivity.this, R.layout.list_items, R.id.checkBox, mArrayList);
                    list = (ListView) findViewById(R.id.myListId);
                    list.setAdapter(listAdapter);
                }
                mDataBaseHelper.close();
            } else {
                toastMessage("the Database is empty");
            }
        }catch(Exception e){
            Log.e(TAG, "populateListView: error"+e.getStackTrace() );
        }
    }

когда приложение запускается, я коснулся элемента, который хочу удалить, но вижу, что элементы начинают удаляться по порядку сверху!один за другим каждый раз, когда я нажимал на любой флажок.

Ответы [ 2 ]

0 голосов
/ 03 июня 2019

Вы хотите: -

public void deleteTask(String task) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_NAME, COL2 + "=?" , new String[]{task});
}

Если бы вы не улавливали ошибку, используя try / catch, используя db.delete(TABLE_NAME, COL2 , new String[]{task});, вы получите исключение в виде: -

java.lang.IllegalArgumentException: Too many bind arguments.  1 arguments were provided but the statement needs 0 arguments.

Однако

Предполагается, что проблема с последовательным удалением строк, а не в соответствии с отмеченными элементами, вероятно, связана с обработкой отмеченных элементов. Однако, поскольку код для этого не предоставлен, было бы только догадываться, где в коде вы ошибаетесь.

Во-первых, вы не хотите создавать новый экземпляр listadapter каждый раз при заполнении ListView.

В качестве подсказки для обработки ListView, но для удаления элемента, когда он долго нажимается на основе значения COL2, возможно, рассмотрим следующее, основанное на вашем коде (но удаляющее в соответствии с длительным щелчком по элементу): -

public void populateLisView() {
    mDataBaseHelper = new DataBaseHelper(this);  //<<<<<<<<<< NOTE 1
    list = (ListView) this.findViewById(R.id.myListId); //<<<<<<<<<< NOTE 1
    data = mDataBaseHelper.getData(); //<<<<<<<<<< get the data to be listed

    if (listadapter == null) { //<<<<<<<<<< Only need to instantiate one adapter when it has not bee instantiated
        listadapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,android.R.id.text1,data); // for convenience using a stock layout
        list.setAdapter(listadapter);
        //<<<<<<<<<<< add the onItemLongClick listener
        list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                mDataBaseHelper.deleteTaskByCol2(data.get(position)); //<<<<<<<<<< gets the value of the item according to it's position in the list
                populateLisView(); //<<<<<<<<<< as the item has been deleted then refresh the Listview
                return true; // flag the event as having been handled.
            }
        });
    //<<<<<<<<<<< If the Adapter has been instantiated then refresh the ListView's data
    } else {
        listadapter.clear(); // Clear the data from the adapter
        listadapter.addAll(data); // add the new changed data to the adapter
        listadapter.notifyDataSetChanged(); // tell the adapter that the data has changed
    }
}
  • ПРИМЕЧАНИЕ 1

    • вы обычно создаете эти переменные один раз.
  • Проверьте комментарии

Вы можете отредактировать свой вопрос, указав, как вы обрабатываете события проверки.

Полный рабочий пример

DatabaseHelper.java

  • Обратите внимание, это может немного отличаться от вашего

    открытый класс DataBaseHelper расширяет SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    
    public static final String TABLE_NAME = "mytable";
    public static final String COL1 = "col1";
    public static final String COL2 = "col2";
    
    SQLiteDatabase db;
    
    private static final String CRT_MYTABLE_SQL = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
            "(" +
            COL1 + " TEXT, " +
            COL2 + " TEXT" +
            ")";
    public DataBaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        db = this.getWritableDatabase();
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CRT_MYTABLE_SQL);
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
    }
    
    public long addMytableRow(String col1, String col2) {
        ContentValues cv = new ContentValues();
        cv.put(COL1,col1);
        cv.put(COL2,col2);
        return db.insert(TABLE_NAME,null,cv);
    }
    
    public ArrayList<String> getData() {
        ArrayList<String> rv = new ArrayList<>();
        Cursor csr = db.query(TABLE_NAME,null,null,null,null,null,null);
        while (csr.moveToNext()) {
            rv.add(csr.getString(csr.getColumnIndex(COL2)));
        }
        csr.close();
        return rv;
    }
    
    public void deleteTaskByCol2(String task) {
        db.delete(TABLE_NAME,COL2 + "=?",new String[]{task});
    }
    

    }

* * MainActivity.java тысяча сорок-девять

т.е. пример действия, основанного на вашем коде, но согласно приведенному выше: -

public class MainActivity extends AppCompatActivity {

    DataBaseHelper mDataBaseHelper;
    ArrayList<String> data;
    ListView list;
    ArrayAdapter<String> listadapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addSomeTestData();
        populateLisView();
    }

    private void example001() {
    }

    public void populateLisView() {
        mDataBaseHelper = new DataBaseHelper(this);
        list = (ListView) this.findViewById(R.id.myListId);
        data = mDataBaseHelper.getData();
        if (listadapter == null) {
            listadapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,android.R.id.text1,data);
            list.setAdapter(listadapter);
            list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    //mDataBaseHelper.deleteTaskWrong(data.get(position)); // ooops
                    mDataBaseHelper.deleteTaskByCol2(data.get(position));
                    populateLisView();
                    return true;
                }
            });
        } else {
            listadapter.clear();
            listadapter.addAll(data);
            listadapter.notifyDataSetChanged();
        }
    }

    private void addSomeTestData() {
        if (mDataBaseHelper == null) {
            mDataBaseHelper = new DataBaseHelper(this);
        }
        if (DatabaseUtils.queryNumEntries(mDataBaseHelper.getWritableDatabase(),DataBaseHelper.TABLE_NAME) > 0) return;
        mDataBaseHelper.addMytableRow("Test1","Test1");
        mDataBaseHelper.addMytableRow("Test2","Test2");
        mDataBaseHelper.addMytableRow("Test3","Test3");
        mDataBaseHelper.addMytableRow("Test4","Test4");
    }
}
  • Примечание. AddSomeTestData добавляет некоторые данные для тестирования / демонстрации.

Результат

При первом запуске: -

enter image description here

После долгого щелчка Тест 2

enter image description here

т.е. удаленный элемент был удален (из списка и базы данных), а список обновлен.

0 голосов
/ 03 июня 2019

Попробуйте заменить

db.delete(TABLE_NAME, COL2 , new String[]{task});

на

db.delete(TABLE_NAME, COL2 + " = ?" , new String[]{task});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...