有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从游标适配器/列表视图中删除多个元素

我正在用Android/Java做一个项目。我有一个带有listview的活动,它显示数据库中的值,还有一个remove按钮。目前,此列表视图的每一行都包含一个checktextview。最后一个显示数据库元素的名称。我想选择不同的元素(使用“检查文本”视图),然后如果我按下“删除”按钮,所有选定的元素都必须从列表和数据库中删除。在下面,我把我的课程的基本部分。我已经完成了大部分工作。 这是我的活动:

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 = "List_1";
    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
}
}

这是我的自定义适配器:

public class ShoppingListViewAdapter extends CursorAdapter {

private LayoutInflater layoutInflater;
private List<Integer> elementsPosArrayList = new ArrayList<>();
private HashMap<String, Integer> elementsMap = new HashMap<>();

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<Integer> getElementsPosArrayList() {
    return elementsPosArrayList;
}
}

数据库管理的类如下所示: 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 = "CREATE TABLE " + DBFieldsShoppingList.FIELD_TABLE_NAME +
            " ( _id INTEGER PRIMARY KEY AUTOINCREMENT," +
            DBFieldsShoppingList.FIELD_ELEMENT_NAME + " TEXT," +
            DBFieldsShoppingList.FIELD_ELEMENT_TYPE + " TEXT," +
            DBFieldsShoppingList.FIELD_ELEMENT_QUANT + " TEXT)";
    shoppingListDB.execSQL(q);
}
@Override
public void onUpgrade(SQLiteDatabase shoppingListDB, int oldVersion, int newVersion) {}
}

为数据库的字段初始化:

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

类数据库管理器:

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 + "=?", new String[]{Long.toString(id)})>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;
}
}

在adapter类的bindView方法中,我想保存元素名和位置之间的映射。然后,创建选中元素的元素名称列表。通过这种方式,我可以从地图上知道选中元素的位置。现在,我必须使用数据库管理器类的delete方法获取选中元素的索引,以便从数据库中删除它们。 我怎样才能解决这个问题?如果我的结构不正确,请告诉我如何改变。 事先非常感谢

马可


共 (1) 个答案

  1. # 1 楼答案

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

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

    这允许在数据库中按名称搜索。 在adapter类中,我删除了映射,并编写了一个字符串的arraylist,其中我将选中元素的名称放在:

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

    最后,在activity类中,remove方法如下所示:

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

    就这样我解决了我的问题

    马可