Как заставить SQLite работать с моими флажками - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть действие, которое состоит из ExpandableListView с более чем 30 флажками.Поскольку я уже использую 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);
    }
}

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Вы можете использовать один тип столбца (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. все строки

enter image description here

Выберите строки, в которых установлен 64-й флажок (только 3-й ряд)

enter image description here

выберите строки, в которых установлены 1-й и 6-й флажки (только 1-й ряд)

enter image description here

Принцип работы Android

Следующий код представляет собой простую демонстрацию того, как вышеуказанное можно использовать в простом приложении для Android.

Приложение имеет

  • две кнопки (СОХРАНИТЬ, чтобы сохранить запись, и ЛОГ.Описывать сохраненные записи с точки зрения флажков).
  • 6 флажков

Похоже (после того, как некоторые флажки были установлены / отмечены): -

enter image description here

При добавлении нескольких записей (нажатие кнопки SAVE) выходные данные в журнале могут быть: -

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);
    }
}
0 голосов
/ 28 ноября 2018

Если вы сохраняете состояние флажков в вашей базе данных SQLite, я бы рекомендовал использовать более 30 строк только с одним столбцом.

Это потому, что завтра представьте, что вам нужно добавить еще одинфлажок, вам нужно будет изменить таблицу, чтобы добавить еще один столбец для нового флажка (изменить схему БД), в то время как если вы используете одну строку для каждого флажка, вам просто нужно добавить одну строку.

Я думаю, что это более эффективный способ.


РЕДАКТИРОВАТЬ

В ответ на ваш комментарий, если поездка имеет свой собственный набор состояний флажков, может бытьЧтобы сохранить это без добавления большого количества строк / столбцов, можно добавить в свою (как я предполагаю) таблицу командировок еще один столбец, в котором вы можете иметь состояние всех флажков только в одной ячейке.

Я бы согласился сохранить двоичную строку длиной 30+.(таким образом, каждый из символов идет за одно состояние флажка).

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

Это будетсохранить только одну строку для всех флажков, например (с примером из 31 флажка):

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