【问题标题】:How to get SQLite to work with my Checkboxes如何让 SQLite 与我的复选框一起使用
【发布时间】:2018-11-28 14:42:26
【问题描述】:

我有一个包含大约 30 多个复选框的 ExpandableListView 的活动。因为我已经在使用 SQLite 在我的 android 应用程序中存储其他信息。我希望能够在我的 SQLite 中存储复选框状态(选中/未选中)。现在的问题是,如果我创建一个专门用于存储所有 30+ 复选框的表,这意味着我需要在该表的单行中包含 30+ 列?有没有更简单的方法来使用 SQLite 存储它们?

下面是我的清单的 ExpandableListView 代码:-

public class Checklist extends AppCompatActivity {

    //  ExpandableListAdapter listAdapter;
    ExpListViewAdapterWithCheckbox listAdapter;
    ExpandableListView expListView;
    ArrayList<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    public TextView name_checklist;

    DatabaseHelper myDb;

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

        myDb = new DatabaseHelper(this);

        final int position = getIntent().getExtras().getInt("Position");

        TextView name_checklist = (TextView) findViewById(R.id.checklistname);

        Cursor gettripname = myDb.getTripName(position+1);
        if (gettripname.getCount() == 0) {
            Toast.makeText(Checklist.this, "No amount found !", Toast.LENGTH_LONG).show();
        } else {
            gettripname.moveToFirst();
            String temp = gettripname.getString(0);
            name_checklist.setText(temp+ " Trip Checklist");
        }

        // get the listview
        expListView = (ExpandableListView) findViewById(R.id.lvExp);

        // preparing list data
        prepareListData();

        listAdapter = new ExpListViewAdapterWithCheckbox(this, listDataHeader, listDataChild);

        // setting list adapter
        expListView.setAdapter(listAdapter);

        // Listview Group click listener
        expListView.setOnGroupClickListener(new OnGroupClickListener() {

            @Override
            public boolean onGroupClick(ExpandableListView parent, View v,
                                        int groupPosition, long id) {
                // Toast.makeText(getApplicationContext(),
                // "Group Clicked " + listDataHeader.get(groupPosition),
                // Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        // Listview Group expanded listener
        expListView.setOnGroupExpandListener(new OnGroupExpandListener() {

            @Override
            public void onGroupExpand(int groupPosition) {
                Toast.makeText(getApplicationContext(),
                        listDataHeader.get(groupPosition) + " Expanded",
                        Toast.LENGTH_SHORT).show();
            }
        });

        // Listview Group collasped listener
        expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {

            @Override
            public void onGroupCollapse(int groupPosition) {
                Toast.makeText(getApplicationContext(),
                        listDataHeader.get(groupPosition) + " Collapsed",
                        Toast.LENGTH_SHORT).show();

            }
        });

        // Listview on child click listener
        expListView.setOnChildClickListener(new OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                Toast.makeText(
                        getApplicationContext(),
                        listDataHeader.get(groupPosition)
                                + " : "
                                + listDataChild.get(
                                listDataHeader.get(groupPosition)).get(
                                childPosition), Toast.LENGTH_SHORT)
                        .show();
                return false;
            }
        });


    }


    private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding header data
        listDataHeader.add("Toiletries");
        listDataHeader.add("Clothes");
        listDataHeader.add("Essentials");
        listDataHeader.add("Travel Comfort");
        //listDataHeader.add("")

        // Adding child data
        List<String> toiletries = new ArrayList<String>();
        toiletries.add("Bandages");
        toiletries.add("Contacts");
        toiletries.add("Contacts Solution");
        toiletries.add("Cologne");
        toiletries.add("Conditioner");
        toiletries.add("Cotton Buds");
        toiletries.add("Deodorant");
        toiletries.add("Hairbrush");
        toiletries.add("Nail Clippers");
        toiletries.add("Razor");
        toiletries.add("Shampoo");
        toiletries.add("Shaving Gel");
        toiletries.add("Toothbrush");
        toiletries.add("Toothpaste");

        List<String> clothes = new ArrayList<String>();
        clothes.add("Belt ");
        clothes.add("Bras");
        clothes.add("Casual Pants");
        clothes.add("Casual Shirts");
        clothes.add("Heavy Coat");
        clothes.add("Jumper");
        clothes.add("Light Jacket");
        clothes.add("Pyjamas");
        clothes.add("Scarf");
        clothes.add("Shoes");
        clothes.add("Shorts");
        clothes.add("Socks");
        clothes.add("Swimwear");

        List<String> essentials = new ArrayList<String>();
        essentials.add("Digital Camera");
        essentials.add("Headache Pills");
        essentials.add("Fever Pills");
        essentials.add("Diarrhea Pills");
        essentials.add("Flu Pills");
        essentials.add("Cough Medicine");
        essentials.add("Powerbank");
        essentials.add("USB Power Socket");
        essentials.add("Sunglasses");
        essentials.add("Earphones");

        List<String> travelcomfort = new ArrayList<String>();
        travelcomfort.add("Travel Pillow");
        travelcomfort.add("Travel Blanket");
        travelcomfort.add("Eye Mask");
        travelcomfort.add("Ear Plugs");
        travelcomfort.add("Books");
        travelcomfort.add("Magazines");
        travelcomfort.add("Card games");


        listDataChild.put(listDataHeader.get(0), toiletries); // Header, Child data
        listDataChild.put(listDataHeader.get(1), clothes);
        listDataChild.put(listDataHeader.get(2), essentials);
        listDataChild.put(listDataHeader.get(3), travelcomfort);
    }
}

【问题讨论】:

    标签: android sqlite expandablelistview checklistbox


    【解决方案1】:

    如果您将复选框的状态存储在 SQLite DB 中,我建议使用 30 多行和一列。

    这是因为,假设明天您需要再添加一个复选框,您将需要更改表格以为新复选框添加一列(更改您的数据库架构),而如果您为每个复选框使用一行,您只需要添加一行。

    我认为这是一种更有效的方式。


    编辑

    针对您的评论,如果旅行有他自己的复选框状态集,那么在不添加大量行/列的情况下保存它的方法可能是添加到您的(我假设)旅行表中,多一列,您可以在其中仅在一个单元格中查看所有复选框的状态。

    我会用它来保存一个 30+ 长度的二进制字符串。 (所以每个字符都对应一个复选框状态)。

    这种方法的缺点是您应该解析状态以保存它们并解析它们以读取它们。

    这将只为所有复选框保存一个字符串,例如(以 31 个复选框为例):

    0000000000000000000000000000001 (just the last checkbox is enabled)
    1000000000000000000000000000001 (first and last checkbox are enabled) 
    

    【讨论】:

    • 明白,但因为我正在做一个旅行应用程序,每次旅行都有自己的清单,所以我不能有一个超过 30 行的表格,因为一旦用户创建,我需要添加一个新行另一个旅行。有什么方法可以简化并向我展示如何根据我的代码在我的 SQLite 中保存复选框状态?
    • 哇,这听起来是个不错的解决方案!知道在哪里可以获得教程以将其实现到我的代码中吗? :D
    • 你在那个问题上抓住了我 :( 。难道没有办法迭代你在 listDataChild 中添加的所有复选框吗?如果有,只需遍历它们并附加 0 或 1以防它被选中。
    【解决方案2】:

    您可以使用单列类型 (INTEGER),即存储和检索为 java long (your_cursor.getLong())。

    然后您最多可以有 64 个复选框(每位 1 个)。

    下面显示了如何根据列中存储的数据操作复选框,基于第一个为 0,最后一个为 63(即设置复选框或测试复选框)。

    一个活动被用来测试并产生了一些结果。

    :-

    public class CheckList extends AppCompatActivity {
    
    
        // The value stored in a column (rightmost bit  represents first checkbox, ... leftmost bit represents 64th checkbox)
        long db_value = (long) 0b11010000_00000000_00000000_00000000_01100000_00000000_00000000_00010101L;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_check_list);
            db_value = setCheckBox(db_value,8); // set the 9th (offset 8)
            db_value = setCheckBox(db_value,0); //already set
    
            // Inspect and report on all 64 checkboxes
            for (int i=0;i < 64; i++) {
                Log.d(
                        "CHECKBOX CHECKED",
                        "Checked Offset " + String.valueOf(i) +
                                " checked value is " + String.valueOf(
                                        isCheckBoxNChecked(db_value,i)
                        )
                );
            }
        }
    
        /**
         * test to see if checkbox n (0-63) is set
         * @param value_from_db_column  the value extracted from the db that represents all checkboxes
         * @param checkbox_to_check the checkbox to be tested
         * @return true if checked else false
         */
        public boolean isCheckBoxNChecked(long value_from_db_column, int checkbox_to_check) {
             return BigInteger.valueOf(value_from_db_column).testBit(checkbox_to_check);
        }
    
        /**
         * Set checkbox n (0-63)
         * @param current_checkbox  the current checkbox status
         * @param checkbox_to_set   the checkbox to be set
         * @return the amended checkbox status
         */
        public long setCheckBox(long current_checkbox, int checkbox_to_set) {
            return BigInteger.valueOf(current_checkbox).setBit(checkbox_to_set).longValue();
        }
    }
    

    结果

    D/CHECKBOX CHECKED: Checked Offset 0 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 1 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 2 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 3 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 4 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 5 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 6 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 7 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 8 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 9 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 10 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 11 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 12 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 13 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 14 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 15 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 16 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 17 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 18 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 19 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 20 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 21 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 22 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 23 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 24 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 25 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 26 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 27 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 28 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 29 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 30 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 31 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 32 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 33 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 34 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 35 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 36 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 37 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 38 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 39 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 40 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 41 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 42 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 43 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 44 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 45 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 46 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 47 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 48 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 49 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 50 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 51 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 52 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 53 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 54 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 55 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 56 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 57 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 58 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 59 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 60 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 61 checked value is false
    D/CHECKBOX CHECKED: Checked Offset 62 checked value is true
    D/CHECKBOX CHECKED: Checked Offset 63 checked value is true
    

    SQL 示例

    以下是如何使用 SQL 进行一些操作:-

    DROP TABLE IF EXISTS mycheckboxes;
    CREATE TABLE IF NOT EXISTS mycheckboxes (id INTEGER PRIMARY KEY, USER TEXT, checkbox INTEGER);
    INSERT INTO mycheckboxes (user,checkbox) VALUES
        ('Fred', (1 << 0) + (1 << 5) + (1 << 7)),
        ('Fred', 0 + (1 << 3) + (1 << 5) + (1 << 8)),
        ('Fred', 0 + (1 << 2) + (1 << 4) + (1 << 63))
    ;
    -- Show all
    SELECT * FROM mycheckboxes;
    -- Only select rows where 64th checkbox is checked
    SELECT * FROM mycheckboxes WHERE checkbox & (1 << 63) <> 0;
    -- Only select rows where 1st and 6th checkboxes are set
    SELECT * FROM mycheckboxes WHERE checkbox & (1 << 0) <> 0 AND checkbox & (1 << 5) <> 0;
    
    • 创建名为 mycheckboxes 的表
    • 添加 3 行
      • 第 1 行设置了第 1、6 和 8 个复选框
      • 第 2 行设置了第 4、第 6 和第 9 个复选框
      • 第 3 行设置了第 3 个第 5 个和第 64 个复选框

    结果:-

    1. 所有行

    1. 选择选中第 64 个复选框的行(仅第 3 行)

    1. 选择设置了第 1 和第 6 个复选框的行(仅第 1 行)

    Android Demo原理

    以下代码是如何在一个简单的 Android 应用中使用上述代码的简单演示。

    该应用有

    • 两个按钮(SAVE 用于保存条目,LOG IT 用于从复选框的角度报告已保存的条目)。
    • 6 个复选框

    看起来(在设置/检查了一些复选框之后):-

    添加几个条目(点击保存)后,日志中的输出可能是:-

    1-29 02:44:52.803 3633-3633/so53521994numerouscheckboxes.so53521994numerouscheckboxes D/LOGCHECKBOX: For row 1 checkboxes value is 13
            Checkbox 1 is CHECKED.
            Checkbox 2 is  NOT CHECKED.
            Checkbox 3 is CHECKED.
            Checkbox 4 is CHECKED.
            Checkbox 5 is  NOT CHECKED.
            Checkbox 6 is  NOT CHECKED.
    11-29 02:44:52.803 3633-3633/so53521994numerouscheckboxes.so53521994numerouscheckboxes D/LOGCHECKBOX: For row 2 checkboxes value is 42
            Checkbox 1 is  NOT CHECKED.
            Checkbox 2 is CHECKED.
            Checkbox 3 is  NOT CHECKED.
            Checkbox 4 is CHECKED.
            Checkbox 5 is  NOT CHECKED.
            Checkbox 6 is CHECKED.
    
    • 第 2 行是上面添加的条目。

    代码

    数据库助手 DatabaseHelper.java :-

    public class DatabaseHelper extends SQLiteOpenHelper {
    
        public static final String DBNAME = "mycheckboxes.db";
        public static final int DBVERSION = 1;
    
        public static final String CHECKBOX_TABLE = "mycheckboxes";
        public static final String CHECKBOX_COL_ID = BaseColumns._ID;
        public static final String CHECKBOX_COL_USER = "user";
        public static final String CHECKBOX_COL_CHECKBOX = "checkbox";
    
        SQLiteDatabase mDB;
    
    
        public DatabaseHelper(Context context) {
            super(context, DBNAME, null, DBVERSION);
            mDB = this.getWritableDatabase();
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
    
            String crt_checkbox_table = "CREATE TABLE IF NOT EXISTS " + CHECKBOX_TABLE + "(" +
                    CHECKBOX_COL_ID + " INTEGER PRIMARY KEY, " +
                    CHECKBOX_COL_USER + " TEXT, " +
                    CHECKBOX_COL_CHECKBOX + " INTEGER" +
                    ")";
            db.execSQL(crt_checkbox_table);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int i, int i1) {}
    
        public long insertEntry(String user, long checkboxes) {
            ContentValues cv = new ContentValues();
            cv.put(CHECKBOX_COL_USER,user);
            cv.put(CHECKBOX_COL_CHECKBOX,checkboxes);
            return mDB.insert(CHECKBOX_TABLE,null,cv);
        }
    
        public void logCheckBoxStatusForUser(String user, int checkbox_count) {
            String whereclause = CHECKBOX_COL_USER + "=?";
            String[] whereargs = new String[]{user};
            Cursor csr = mDB.query(
                    CHECKBOX_TABLE,
                    null,
                    whereclause,
                    whereargs,
                    null,
                    null,
                    null
            );
            while (csr.moveToNext()) {
                long currrent_checkboxes = csr.getLong(csr.getColumnIndex(CHECKBOX_COL_CHECKBOX));
                StringBuilder sb = new StringBuilder("For row ")
                        .append(String.valueOf(csr.getPosition() + 1))
                        .append(" checkboxes value is ")
                        .append(String.valueOf(currrent_checkboxes));
                for (int i = 0; i < checkbox_count; i++) {
                    sb.append("\n\tCheckbox ")
                            .append(String.valueOf(i+1))
                            .append(" is ");
                    if (CheckList.isCheckBoxNChecked(currrent_checkboxes,i)) {
                        sb.append("CHECKED.");
                    } else  {
                        sb.append(" NOT CHECKED.");
                    }
                }
                Log.d("LOGCHECKBOX",sb.toString());
            }
        }
    }
    

    活动 CheckList.java :-

    public class CheckList extends AppCompatActivity {
    
    
        CheckBox[] checkboxes = new CheckBox[6];
        Button save,logit;
        DatabaseHelper mDBHlpr;
    
        String current_user = "Fred";
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_check_list);
    
            mDBHlpr = new DatabaseHelper(this);
    
            checkboxes[0] = this.findViewById(R.id.cb01);
            checkboxes[1] = this.findViewById(R.id.cb02);
            checkboxes[2] = this.findViewById(R.id.cb03);
            checkboxes[3] = this.findViewById(R.id.cb04);
            checkboxes[4] = this.findViewById(R.id.cb05);
            checkboxes[5] = this.findViewById(R.id.cb06);
            save = this.findViewById(R.id.savebutton);
    
            save.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    save_to_db();
                }
            });
    
            logit = this.findViewById(R.id.logitbutton);
            logit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mDBHlpr.logCheckBoxStatusForUser(current_user,checkboxes.length);
                }
            });
        }
    
        /**
         * test to see if checkbox n (0-63) is set
         * @param value_from_db_column  the value extracted from the db that represents all checkboxes
         * @param checkbox_to_check the checkbox to be tested
         * @return true if checked else false
         */
        public static boolean isCheckBoxNChecked(long value_from_db_column, int checkbox_to_check) {
             return BigInteger.valueOf(value_from_db_column).testBit(checkbox_to_check);
        }
    
        /**
         * Set checkbox n (0-63)
         * @param current_checkbox  the current checkbox status
         * @param checkbox_to_set   the checkbox to be set
         * @return the amended checkbox status
         */
        public long setCheckBox(long current_checkbox, int checkbox_to_set) {
            return BigInteger.valueOf(current_checkbox).setBit(checkbox_to_set).longValue();
        }
    
        private void save_to_db() {
            long checkboxes_to_save = 0L;
            for (int i =0; i < checkboxes.length; i++) {
                if (checkboxes[i].isChecked()) {
                    checkboxes_to_save = setCheckBox(checkboxes_to_save,i);
                }
            }
            mDBHlpr.insertEntry(current_user,checkboxes_to_save);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多