如何根据DataBase中的信息制作复选框?

时间:2017-11-28 14:05:23

标签: android listview arraylist android-sqlite checkboxlist

我在DataBase中有一个表,我想创建一个表。 现在,根据表格中的信息,我会做很多CheckBox,只显示其中一些是没有意义的。我听说过 但是我如何 我在互联网上找到的例子,当我尝试插入大量信息时,只有一半信息进来,所以我被告知做。 你有一个如何做到这一点的例子吗?

它是DatabaseHandler:

package budgetreport.com.budgetreport;

public class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 4;

    // Database Name
    private static final String DATABASE_NAME = "Records_Item Purcashes";

    // Contacts table name
    private static final String TABLE_RECORDS = "Records";

    // Contacts Table Columns names
    private static final String KEY_ID = "ID";
    private static final String KEY_PRICE = "Price";
    private static final String KEY_ITEM = "Item";
    private static final String KEY_DETAILS = "Details";
    private static final String KEY_DATE = "Date";

    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_RECORDS + "("
                + KEY_ID + " INTEGER PRIMARY KEY,"
                + KEY_PRICE + " INTEGER," + KEY_ITEM + " TEXT,"
                + KEY_DETAILS + " TEXT, " + KEY_DATE + " TEXT" + ")";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECORDS);

        // Create tables again
        onCreate(db);
    }
    // Adding new contact
    public void addRecord(Record record) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put(KEY_ID, record.getId()); // Contact Name
        values.put(KEY_PRICE, record.getPrice()); // Contact Name
        values.put(KEY_ITEM, record.getItem()); // Contact Name
        values.put(KEY_DETAILS, record.getDetails()); // Contact Name
        values.put(KEY_DATE, record.getDetails()); // Contact Phone Number

        // Inserting Row
        db.insert(TABLE_RECORDS, null, values);
        db.close(); // Closing database connection
    }
    // Getting single contact
    public Record getRecord(int id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_RECORDS, new String[] { KEY_ID, KEY_PRICE,
                        KEY_ITEM, KEY_DETAILS, KEY_DATE }, KEY_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        Record record = new Record(Integer.parseInt(cursor.getString(0)),
                Integer.parseInt(cursor.getString(1)), cursor.getString(2), cursor.getString(3), cursor.getString(4));
        // return contact
        return record;
    }
    // Getting All Contacts
    public List<Record> getAllContacts() {
        List<Record> contactList = new ArrayList<Record>();
        // Select All Query
        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Record record = new Record();
                record.setId(Integer.parseInt(cursor.getString(0)));
                record.setPrice(Integer.parseInt(cursor.getString(1)));
                record.setItem(cursor.getString(2));
                record.setDetails(cursor.getString(3));
                record.setDate(cursor.getString(4));

                // Adding contact to list
                contactList.add(record);
            } while (cursor.moveToNext());
        }

        // return contact list
        return contactList;
    }
    // Getting contacts Count
    public int getRecordsCount() {
        String countQuery = "SELECT  * FROM " + TABLE_RECORDS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
       // cursor.close();

        // return count
        return cursor.getCount();
    }
    // Updating single contact
    public int updateContact(Record record) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_ID, record.getId());
        values.put(KEY_PRICE, record.getPrice());
        values.put(KEY_DETAILS, record.getDetails());
        values.put(KEY_DATE, record.getDate());

        // updating row
        return db.update(TABLE_RECORDS, values, KEY_ID + " = ?",
                new String[] { String.valueOf(record.getPrice()) });
    }
    // Deleting single contact
    public void deleteContact(Record record) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_RECORDS, KEY_ID + " = ?",new String[] 
       {String.valueOf(record.getPrice()) });
        db.close();
    }
}

1 个答案:

答案 0 :(得分:2)

删除已检查的项目我想删除我标记的行。

进展相对简单。

涉及到 - a)向数据库助手添加一个方法,根据id删除。 - b)(i)修改onClick监听器以调用delete方法(简单循环),然后(ii)更新listview(循环之后)。

但是,原始的自定义适配器有一些缺陷,原始光标是通过mCsr保留的,并且没有考虑更改Cursor(交换)时更改的复选框数。

因此,适配器已经删除了对mCsr的引用,并被传递的Cursor或通过调用getCursor方法替换。此外,swapCursor()方法已被覆盖,以调整mCheckBoxes的元素数量并重新初始化elemnets(设置为false)。

a)新的 deleteRecord 方法: -

public boolean deleteRecord(long id) {
    SQLiteDatabase db = this.getWritableDatabase();
     return (db.delete(TABLE_RECORDS,KEY_ID + "=?",new String[]{Long.toString(id)})> 0);
}

b)(i) onCLickListener 修正案(注意包括将所有删除分组到单个交易中): -

    // <<<<< DO IT BUTTON HANDLER i.e. get list of ID's for checked items
    mDoItButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get the ID's for the checked Items
            mCheckedIdList = mMCA.getCheckedRecordIdList();
            Toast.makeText(mContext,"You have " + mCheckedIdList.length + " Items checked.",Toast.LENGTH_SHORT).show();
            //<<<< to delete
            SQLiteDatabase db = mDBHandler.getWritableDatabase();
            db.beginTransaction();
            for (long id: mCheckedIdList) {
                mDBHandler.deleteRecord(id);
            }
            db.setTransactionSuccessful();
            db.endTransaction();
            refreshListView();
        }
    });

b(ii)更新 Listview (活动中的新方法): -

private void refreshListView() {
    mCsr = mDBHandler.getAllRecords();
    mMCA.swapCursor(mCsr);
}

备注

  • 这是作为活动的方法添加的。
  • mMCA.notifyDatasetChanged();是一种替代方案(我个人更喜欢'swapCursor1,因为它更具决定性)。

修改后的自定义光标适配器应为: -

public class MyCustomCursorAdapter extends CursorAdapter {

    private Context mContext;
    private String[] mColumns;
    private int[] mViews;
    private int mLayout;
    private boolean[] mCheckBoxStates;
    private int mCheckBoxView;

    // Constructor for the Custom Cursor Adapter
    MyCustomCursorAdapter(Context context, int layout, Cursor csr, String[] from_columns, int[] to_views, int checkbox_view) {
        super(context,csr, false);
        mContext = context;
        mLayout = layout;
        mColumns = from_columns;
        mViews = to_views;
        mCheckBoxView = checkbox_view;
    }

    @Override
    // Inflate the layout we are going to use (as passed via 2nd parameter)
    public View newView(Context context, Cursor csr, ViewGroup parent) {
        // Initialise an int array for the checkboxes (all will be 0)
        mCheckBoxStates = new boolean[csr.getCount()];
        return LayoutInflater.from(context).inflate(mLayout,parent,false);
    }

    @Override
    // Tie the from_columns to the display views
    public void bindView(View view, Context context, Cursor csr) {

        final Cursor fcsr = csr;

        // Place the data from the cursor into the respective View (TextView)
        for (int i = 0; i < mColumns.length; i++) {
            ((TextView) view.findViewById(mViews[i])).setText(csr.getString(csr.getColumnIndex(mColumns[i])));
        }
        // Set the checkbox (note should be false, unless otherwise changed)
        CheckBox currentCheckBox = (CheckBox) view.findViewById(mCheckBoxView);
        currentCheckBox.setChecked(mCheckBoxStates[csr.getPosition()]);
        currentCheckBox.setTag(new Long(csr.getLong(csr.getColumnIndex(DatabaseHandler.KEY_ID))));

        //
        currentCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            final int position = fcsr.getPosition();
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // Store the checkbox status
                mCheckBoxStates[position] = ((CheckBox) buttonView).isChecked();
                int restore_cursor_position = fcsr.getPosition();
                //Move the Cursor to the respective row
                //NOTE! 1st position in Lisview is 1 but equates to cursor row 0 etc hence -1
                fcsr.moveToPosition(position);
                Toast.makeText(mContext,
                        "You Changed the CheckBox for row " +
                                Integer.toString(position + 1) +
                                " Item is " +
                                fcsr.getString(fcsr.getColumnIndex(DatabaseHandler.KEY_ITEM))
                        ,
                        Toast.LENGTH_SHORT
                ).show();
                //restore the Cursor's position
                fcsr.moveToPosition(restore_cursor_position);
            }
        });
    }

    // get the list of items (the ID's as long) that have been checked.
    public long[] getCheckedRecordIdList() {

        Cursor csr = this.getCursor();

        // using ArrayList as we can add as we don't yet know how many
        ArrayList<Long> rva = new ArrayList<>();
        // Just in case save the current position of the Cursor
        int restore_cursor_position = csr.getPosition();
        // Loop through the checkbox states
        for (int i=0; i < mCheckBoxStates.length; i++) {
            // If the checkbox reflected as being checked then handle, else ignore it
            if (mCheckBoxStates[i]) {
                // Move to the respective cursor row
                csr.moveToPosition(i);
                // get the respective ID and store in the arraylist
                rva.add(csr.getLong(csr.getColumnIndex(DatabaseHandler.KEY_ID)));
            }
        }
        // Done with the Cursor so re-position it
        csr.moveToPosition(restore_cursor_position);

        // Create the long array to be returned
        long[] rv = new long[rva.size()];
        // Populate the long array with the id's from the arraylist
        for (int i=0; i < rva.size(); i++) {
            rv[i] = rva.get(i);
        }
        // return the long[]
        return rv;
    }


    @Override
    public Cursor swapCursor(Cursor csr) {
        mCheckBoxStates = new boolean[csr.getCount()];
        for (int i=0; i < mCheckBoxStates.length; i++) {
            mCheckBoxStates[i] = false;
        }
        return super.swapCursor(csr);
    }
}