从CursorAdapter/ListView中移除多个元素。

huangapple go评论127阅读模式
英文:

Remove more than one element from CursorAdapter/List View

问题

这是我定制的适配器:

public class ShoppingListViewAdapter extends CursorAdapter {

    // ... (之前的代码)

    public List<Integer> getElementsPosArrayList() {
        return elementsPosArrayList;
    }
}

数据库管理类的相关部分:

public class DBManagerShoppingList {
    private DBHelperShoppingList dbHelperShoppingList;

    // ... (之前的代码)

    public List<Long> getSelectedElementIds(List<Integer> positions) {
        List<Long> selectedIds = new ArrayList<>();
        Cursor crs = query();
        if (crs != null && crs.moveToFirst()) {
            do {
                long id = getElementId(crs, crs.getPosition());
                if (positions.contains(crs.getPosition())) {
                    selectedIds.add(id);
                }
            } while (crs.moveToNext());
            crs.close();
        }
        return selectedIds;
    }
}

ShoppingListActivity 类的 removeSelectedElements 方法中调用数据库管理类的新方法:

public void removeSelectedElements(View btnRemove) {
    List<Integer> selectedPositions = shoppingListViewAdapter.getElementsPosArrayList();
    List<Long> selectedElementIds = dbShoppingList.getSelectedElementIds(selectedPositions);
    for (Long id : selectedElementIds) {
        dbShoppingList.deleteElement(id);
    }
    populateListView();
}

这些更改将帮助你根据选中的元素在数据库中删除相应的条目。请确保将上述更改添加到适当的位置,并根据你的代码结构进行必要的调整。

英文:

I'm making a project in Android/Java. I have an activity with a listview that displays values from a database and a remove button. For the moment, each row of this list view consists of a checktextview. This last one displays the name of an element of the database. I want to select different elements (with the check text view) and then if I press the remove button, all the selected elements have to be removed from the list and from database. In the following I put the essential parts of my classes. I already done most of the work.
This is my activity:

public class ShoppingListActivity extends AppCompatActivity {

// Variables for the management of the database
private DBManagerShoppingList dbShoppingList;
private Cursor crs;
// List view for the shopping list elements
private ListView shoppingListListView;
private ShoppingListViewAdapter shoppingListViewAdapter;
// Generic variables
private String selectedShoppingList;

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

    // Find of the useful widgets
    shoppingListListView = findViewById(R.id.listViewSelShoppingList);
    shoppingListsSpinner = findViewById(R.id.spinnerShoppingLists);
    selectedShoppingList = &quot;List_1&quot;;
    populateListView();
}

// Populate list view from database
public void populateListView() {
    // Database management
    dbShoppingList = new DBManagerShoppingList(this, selectedShoppingList);
    crs = dbShoppingList.query();
    new Handler().post(new Runnable() {
        @Override
        public void run() {
            shoppingListViewAdapter = new ShoppingListViewAdapter(ShoppingListActivity.this, crs, 0);
            shoppingListListView.setAdapter(shoppingListViewAdapter);
        }
    });
}

// Remove selected elements
public void removeSelectedElements(View btnRemove) {
    // TODO
}
}

This is my custom adapter:

public class ShoppingListViewAdapter extends CursorAdapter {

private LayoutInflater layoutInflater;
private List&lt;Integer&gt; elementsPosArrayList = new ArrayList&lt;&gt;();
private HashMap&lt;String, Integer&gt; elementsMap = new HashMap&lt;&gt;();

public ShoppingListViewAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
    return layoutInflater.inflate(R.layout.list_view_row, viewGroup, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    // CheckBox management
    final CheckBox checkBoxElementName = view.findViewById(R.id.checkBoxElementName);
    String elementName = cursor.getString(cursor.getColumnIndex(DBFieldsShoppingList.FIELD_ELEMENT_NAME));
    checkBoxElementName.setText(elementName);
    elementsMap.put(elementName, cursor.getPosition());
    checkBoxElementName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            if (isChecked) {
                elementsPosArrayList.add(elementsMap.get(checkBoxElementName.getText().toString()));
            } else {
                elementsPosArrayList.remove(elementsMap.get(checkBoxElementName.getText().toString()));
            }
        }
    });
}

public long getElementId(Cursor crs, int position) {
    crs.moveToPosition(position);
    return crs.getLong(crs.getColumnIndex(DBFieldsShoppingList.FIELD_ID));
}

public List&lt;Integer&gt; getElementsPosArrayList() {
    return elementsPosArrayList;
}
}

Classes for the database management are the following:
DBHelper:

public class DBHelperShoppingList extends SQLiteOpenHelper {

private String DBName;

public DBHelperShoppingList(@Nullable Context context, int dbVersion, String dbName) {
    super(context, dbName, null, dbVersion);
    this.DBName = dbName;
}

@Override
public void onCreate(SQLiteDatabase shoppingListDB) {
    String q = &quot;CREATE TABLE &quot; + DBFieldsShoppingList.FIELD_TABLE_NAME +
            &quot; ( _id INTEGER PRIMARY KEY AUTOINCREMENT,&quot; +
            DBFieldsShoppingList.FIELD_ELEMENT_NAME + &quot; TEXT,&quot; +
            DBFieldsShoppingList.FIELD_ELEMENT_TYPE + &quot; TEXT,&quot; +
            DBFieldsShoppingList.FIELD_ELEMENT_QUANT + &quot; TEXT)&quot;;
    shoppingListDB.execSQL(q);
}
@Override
public void onUpgrade(SQLiteDatabase shoppingListDB, int oldVersion, int newVersion) {}
}

Class for the fields of the database:

public class DBFieldsShoppingList {
    public static final String FIELD_ID = &quot;_Id&quot;;
    public static final String FIELD_TABLE_NAME = &quot;Shopping_List&quot;;
    public static final String FIELD_ELEMENT_NAME = &quot;Element_Name&quot;;
    public static final String FIELD_ELEMENT_TYPE = &quot;Element_Type&quot;;
    public static final String FIELD_ELEMENT_QUANT = &quot;Element_Quant&quot;;
}

Class database manager:

public class DBManagerShoppingList {
private DBHelperShoppingList dbHelperShoppingList;

public DBManagerShoppingList(Context ctx, String shoppingListName) {
    dbHelperShoppingList = new DBHelperShoppingList(ctx, 1, shoppingListName);
}

public void dbSave(String elementName, String elementType, String elementQuantity) {
    SQLiteDatabase db = dbHelperShoppingList.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(DBFieldsShoppingList.FIELD_ELEMENT_NAME, elementName);
    cv.put(DBFieldsShoppingList.FIELD_ELEMENT_TYPE, elementType);
    cv.put(DBFieldsShoppingList.FIELD_ELEMENT_QUANT, elementQuantity);
    try {
        db.insert(DBFieldsShoppingList.FIELD_TABLE_NAME, null, cv);
    } catch (SQLiteException ignored) {}
}

public boolean deleteElement(long id) {
    SQLiteDatabase db = dbHelperShoppingList.getWritableDatabase();
    try {
        return db.delete(DBFieldsShoppingList.FIELD_TABLE_NAME, DBFieldsShoppingList.FIELD_ID + &quot;=?&quot;, new String[]{Long.toString(id)})&gt;0;
    } catch(SQLiteException exc) {
        return false;
    }
}

public static void deleteDB(Context ctx, String DBName) {
    ctx.deleteDatabase(DBName);
}

public Cursor query() {
    Cursor crs;
    try {
        SQLiteDatabase db = dbHelperShoppingList.getReadableDatabase();
        crs = db.query(DBFieldsShoppingList.FIELD_TABLE_NAME, null, null, null, null, null, null, null);
    } catch (SQLiteException exc) {
        return null;
    }
    return crs;
}
}

I tought, in bindView method of the adapter class, to save a map between element name and its position. Then, to create a list of the element names of the checked elements. In this way, I can know the positions of the checked elements, from the map. Now, I have to get indexes of the checked elements, in order to remove them from database, with delete method of the database manager class.
How can I solve this problem? If my structure is not correct, say me how to change.
Thank you very much in advance.

Marco

答案1

得分: 0

大家好,
我找到了解决方法。在数据库管理类中,我按以下方式更改了删除方法:

public boolean deleteElement(String elementName) {
    SQLiteDatabase db = dbHelperShoppingList.getWritableDatabase();
    try {
        return db.delete(DBFieldsShoppingList.FIELD_TABLE_NAME, DBFieldsShoppingList.FIELD_ELEMENT_NAME + "=?", new String[]{(elementName)}) > 0;
    } catch(SQLiteException exc) {
        return false;
    }
}

这样可以通过名称在数据库中进行搜索。在适配器类中,我移除了映射(map),并且我编写了一个字符串的ArrayList,将选中元素的名称放入其中:

@Override
public void bindView(View view, Context context, Cursor cursor) {
    // 复选框管理
    final CheckBox checkBoxElementName = view.findViewById(R.id.checkBoxElementName);
    String elementName = cursor.getString(cursor.getColumnIndex(DBFieldsShoppingList.FIELD_ELEMENT_NAME));
    checkBoxElementName.setText(elementName);
    checkBoxElementName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            if (isChecked) {
                elementNamesArrayList.add(checkBoxElementName.getText().toString());
            } else {
                elementNamesArrayList.remove(checkBoxElementName.getText().toString());
            }
        }
    });
}

最后,在活动类中,删除方法如下:

public void removeSelectedElements(View btnRemove) {
    List<String> elementNamesArrayList = shoppingListViewAdapter.getElementNamesArrayList();
    for (String item : elementNamesArrayList) {
        dbShoppingList.deleteElement(item);
    }
    populateListView();
}

通过这种方式,我解决了我的问题。

Marco

英文:

Hy to everybody,
I found the solution. In database manager class, I changed the delete method in the following way:

public boolean deleteElement(String elementName) {
    SQLiteDatabase db = dbHelperShoppingList.getWritableDatabase();
    try {
        return db.delete(DBFieldsShoppingList.FIELD_TABLE_NAME, DBFieldsShoppingList.FIELD_ELEMENT_NAME + &quot;=?&quot;, new String[]{(elementName)})&gt;0;
    } catch(SQLiteException exc) {
        return false;
    }
}

This allows, to search by name in database.
In adapter class, I removed the map, and I wrote an arraylist of string, where I put name of the checked elements:

@Override
public void bindView(View view, Context context, Cursor cursor) {
    // CheckBox management
    final CheckBox checkBoxElementName = view.findViewById(R.id.checkBoxElementName);
    String elementName = cursor.getString(cursor.getColumnIndex(DBFieldsShoppingList.FIELD_ELEMENT_NAME));
    checkBoxElementName.setText(elementName);
    checkBoxElementName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            if (isChecked) {
                elementNamesArrayList.add(checkBoxElementName.getText().toString());
            } else {
                elementNamesArrayList.remove(checkBoxElementName.getText().toString());
            }
        }
    });
}

Finally, in the activity class, the remove method is the following:

public void removeSelectedElements(View btnRemove) {
    List&lt;String&gt; elementNamesArrayList = shoppingListViewAdapter.getElementNamesArrayList();
    for (String item: elementNamesArrayList) {
        dbShoppingList.deleteElement(item);
    }
    populateListView();
}

In this way I solved my problem.

Marco

huangapple
  • 本文由 发表于 2020年8月31日 00:52:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63659850.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定