Android:将CheckBox状态存储在CheckList中不同的日期

时间:2018-10-01 06:57:16

标签: java android listview checkbox android-sqlite

我的应用是一个简单的清单。如果我单击一个复选框并关闭该应用程序,则该复选框的状态将在重新启动时保存并重新加载。

现在,我想添加一个日历来选择日期。对于每个新的一天,应取消选中列表中复选框的默认状态。

如果复选框的状态更改,则应在该特定日期保存该复选框。因此,如果我关闭应用程序并再次选择同一天,则应重新加载复选框状态。

如何保存复选框状态,具体取决于日期和列表视图中单击的复选框?

我仍然可以使用sharedPreferences来做到这一点吗?还是我应该使用SQLite,因为使用一年会导致保存3650个复选框状态(假设我的清单包含大约10个项目)。

3 个答案:

答案 0 :(得分:1)

这是逻辑答案。您需要自己实施。

  • 使用SQLite并根据需要的列(根据复选框)创建带有日期字段的表。

  • 现在选择日期后的日期,在数据库中查询所需的日期。并设置复选框(如果该日期存在数据)。

答案 1 :(得分:1)

这是您可以执行SQLite方面的一种方法。

数据库由一个包含11列的表组成。

  • 日期为/名为 _date 的列。
  • 10个列,用于名为 _cb01 _cb02 ,......, _cb10
  • 的复选框

数据库帮助器 DBHelper.java (SQLiteOpenHelper类的子类)具有强制性/覆盖

  • onCreate (创建数据库后运行一次)和
  • onUpgrade (如果数据库版本号增加,则运行, note 不执行任何操作)。
  • >
  • 它有一个只需要上下文的构造函数(因此在使用它的活动中mDB = new DBHelper(this);)。
  • 它具有一种添加行 addNewDayEntry 的方法,该方法将添加没有标记为已设置复选框的行。
  • 它具有一种方法来更新 setDayEntryForOneCheckBox 日期的复选框(1-10)。
  • 它具有一种方法来检查是否在指定日期设置了chekcbox isDayEntryCheckboxSet
  • 有一个私有方法可用于为复选框(1-10)检索适当的列名,即 getCheckboxColumnNameFromNumber

代码是:-

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TB_DAYENTRIES = "day_entries";
    public static final String DAYENTRIES_COL_DATE = "_date";
    public static final String DAYENTRIES_COL_CB01 = "_cb01";
    public static final String DAYENTRIES_COL_CB02 = "_cb02";
    public static final String DAYENTRIES_COL_CB03 = "_cb03";
    public static final String DAYENTRIES_COL_CB04 = "_cb04";
    public static final String DAYENTRIES_COL_CB05 = "_cb05";
    public static final String DAYENTRIES_COL_CB06 = "_cb06";
    public static final String DAYENTRIES_COL_CB07 = "_cb07";
    public static final String DAYENTRIES_COL_CB08 = "_cb08";
    public static final String DAYENTRIES_COL_CB09 = "_cb09";
    public static final String DAYENTRIES_COL_CB10 = "_cb10";


    SQLiteDatabase mDB;
    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crt_tbl_sql = "CREATE TABLE IF NOT EXISTS " + TB_DAYENTRIES + "(" +
                DAYENTRIES_COL_DATE + " TEXT PRIMARY KEY NOT NULL," +
                DAYENTRIES_COL_CB01 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB02 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB03 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB04 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB05 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB06 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB07 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB08 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB09 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB10 + " INTEGER DEFAULT 0" +
                ")";
        db.execSQL(crt_tbl_sql);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

    public long addNewDayEntry(String date) {
        ContentValues cv = new ContentValues();
        cv.put(DAYENTRIES_COL_DATE,date);
        return mDB.insert(TB_DAYENTRIES,null,cv);
    }

    public int setDayEntryForOneCheckBox(String date, int checkbox) {
        int rv = 0;
        String whereclause = DAYENTRIES_COL_DATE + "=?";
        String[] whereargs = new String[]{date};
        ContentValues cv = new ContentValues();
        switch (checkbox) {
            case 1:
                cv.put(DAYENTRIES_COL_CB01,1);
                break;
            case 2:
                cv.put(DAYENTRIES_COL_CB02,1);
                break;
            case 3:
                cv.put(DAYENTRIES_COL_CB03,1);
                break;
            case 4:
                cv.put(DAYENTRIES_COL_CB04,1);
                break;
            case 5:
                cv.put(DAYENTRIES_COL_CB05,1);
                break;
            case 6:
                cv.put(DAYENTRIES_COL_CB06,1);
                break;
            case 7:
                cv.put(DAYENTRIES_COL_CB07,1);
                break;
            case 8:
                cv.put(DAYENTRIES_COL_CB08,1);
                break;
            case 9:
                cv.put(DAYENTRIES_COL_CB09,1);
                break;
            case 10:
                cv.put(DAYENTRIES_COL_CB10,1);
                break;
        }
        if (cv.size() == 1) {
            rv = mDB.update(TB_DAYENTRIES,cv,whereclause,whereargs);
        }
        return rv;
    }

    public boolean isDayEntryCheckboxSet(String date, int checkbox) {
        boolean rv = false;
        String whereclause = DAYENTRIES_COL_DATE + "=?";
        String[] whereargs = new String[]{date};
        if (checkbox < 1 || checkbox > 10) {
            return rv;
        }
        Cursor csr = mDB.query(TB_DAYENTRIES,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            rv = csr.getInt(csr.getColumnIndex(getCheckboxColumnNameFromNumber(checkbox))) == 1;
        }
        csr.close();
        return rv;
    }

    private String getCheckboxColumnNameFromNumber(int checkbox) {
        switch (checkbox) {
            case 1:
                return DAYENTRIES_COL_CB01;
            case 2:
                return DAYENTRIES_COL_CB02;
            case 3:
                return DAYENTRIES_COL_CB03;
            case 4:
                return DAYENTRIES_COL_CB04;
            case 5:
                return DAYENTRIES_COL_CB05;
            case 6:
                return DAYENTRIES_COL_CB06;
            case 7:
                return DAYENTRIES_COL_CB07;
            case 8:
                return DAYENTRIES_COL_CB08;
            case 9:
                return DAYENTRIES_COL_CB09;
            case 10:
                return DAYENTRIES_COL_CB10;
        }
        return "";
    }
}

MainActivity.java 是一项活动:-

  • 创建DBHelper类的实例(这将使用表创建数据库(因为它调用了getWritableDatbase()方法)。
  • 然后添加一行,设置一些复选框指示符以指示已设置的某些复选框(您将根据对用户界面的不正确操作进行操作。)
  • 然后它经过几天,并将当天的10个复选框的状态写到日志中。

代码是:-

public class MainActivity extends AppCompatActivity {

    DBHelper mDB;
    String[] checkdates = new String[]{"2018-09-10","2018-09-11","2018-09-09"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDB = new DBHelper(this);

        mDB.addNewDayEntry("2018-09-10");
        mDB.setDayEntryForOneCheckBox("2018-09-10",1);
        mDB.setDayEntryForOneCheckBox("2018-09-10",3);
        mDB.setDayEntryForOneCheckBox("2018-09-10",8);
        mDB.setDayEntryForOneCheckBox("2010-09-09",7); //<<<<<<<<<< wont set as DAY ENTRY NOT ADDED

        StringBuilder sb = new StringBuilder("");
        for (String s: checkdates) {
            sb.append("\nChecking Date ").append(s);
            for(int i=1; i <= 10; i++) {
                sb.append("\n\tCHECKBOX ").append(String.valueOf(i)).append(" IS ").append(String.valueOf(mDB.isDayEntryCheckboxSet(s,i)));
            }
        }
        Log.d("CHECKBOX STATES",sb.toString());
    }
} 

产生的输出是:-

10-01 10:17:46.753 1467-1467/? D/CHECKBOX STATES: Checking Date 2018-09-10
        CHECKBOX 1 IS true
        CHECKBOX 2 IS false
        CHECKBOX 3 IS true
        CHECKBOX 4 IS false
        CHECKBOX 5 IS false
        CHECKBOX 6 IS false
        CHECKBOX 7 IS false
        CHECKBOX 8 IS true
        CHECKBOX 9 IS false
        CHECKBOX 10 IS false
    Checking Date 2018-09-11
        CHECKBOX 1 IS false
        CHECKBOX 2 IS false
        CHECKBOX 3 IS false
        CHECKBOX 4 IS false
        CHECKBOX 5 IS false
        CHECKBOX 6 IS false
        CHECKBOX 7 IS false
        CHECKBOX 8 IS false
        CHECKBOX 9 IS false
        CHECKBOX 10 IS false
    Checking Date 2018-09-09
        CHECKBOX 1 IS false
        CHECKBOX 2 IS false
        CHECKBOX 3 IS false
        CHECKBOX 4 IS false
        CHECKBOX 5 IS false
        CHECKBOX 6 IS false
        CHECKBOX 7 IS false
        CHECKBOX 8 IS false
        CHECKBOX 9 IS false
        CHECKBOX 10 IS false
  • 注释
  • 由于没有添加针对这些日期(天)的条目,因此2018-09-10和2018-09-09的所有复选框均为假。
  • mDB.setDayEntryForOneCheckBox("2010-09-09",7); //<<<<<<<<<< wont set as DAY行表明,如果尝试更新未添加条目的日期,则setDatEntryForOneCheckbox方法不会失败。

答案 2 :(得分:1)

从MikeT的答案继续,这是如何执行ListView并在选中复选框时更改基础数据。

您需要将ListView添加到主布局中,例如:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <ListView
        android:id="@+id/cblist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>
  • 文件为activity_Main.xml

Listview的每个项目的布局,例如:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/entrydate"
        android:layout_width="100dp"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb01"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb02"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb03"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb04"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb05"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb06"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb07"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb08"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb09"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <CheckBox
        android:id="@+id/cb10"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
</LinearLayout>
  • 文件为cblist_item.xml

要使日期和复选框都可以由侦听器识别,请添加一个新类,例如

public class CBTag {
    private String mEntrydate;
    private int mCheckBoxNumber;

    public CBTag(String entrydate, int checkboxnumber) {
        this.mEntrydate = entrydate;
        this.mCheckBoxNumber = checkboxnumber;
    }

    public int getCheckBoxNumber() {
        return mCheckBoxNumber;
    }

    public void setCheckBoxNumber(int mCheckBoxNumber) {
        this.mCheckBoxNumber = mCheckBoxNumber;
    }

    public String getEntrydate() {
        return mEntrydate;
    }

    public void setEntrydate(String mEntrydate) {
        this.mEntrydate = mEntrydate;
    }
}
  • 这是CBTag.java

将需要一个自定义适配器,它将对列表中的每个项目使用以上布局,还将使用CBTag对象设置复选框的标签

public class CBListAdapter extends CursorAdapter {

    private Context mContext;
    private DBHelper mDB;

    public CBListAdapter(Context context, Cursor cursor) {
        super(context,cursor,0);
        mContext = context;
        mDB = new DBHelper(mContext);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return  super.getView(position,convertView,parent);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        return LayoutInflater.from(mContext).inflate(R.layout.cblist_item,viewGroup,false);
    }

    @Override
    public void bindView(View view, Context context, Cursor csr) {

        TextView entrydate = view.findViewById(R.id.entrydate);
        String entry_date = csr.getString(csr.getColumnIndex(DBHelper.DAYENTRIES_COL_DATE));
        entrydate.setText(entry_date);


        CheckBox[] cblist = new CheckBox[]{
                view.findViewById(R.id.cb01),
                view.findViewById(R.id.cb02),
                view.findViewById(R.id.cb03),
                view.findViewById(R.id.cb04),
                view.findViewById(R.id.cb05),
                view.findViewById(R.id.cb06),
                view.findViewById(R.id.cb07),
                view.findViewById(R.id.cb08),
                view.findViewById(R.id.cb09),
                view.findViewById(R.id.cb10)
        };
        // For Each CheckBox set the tag as a CBTag object (Holds String for date and int for CheckBox #)
        // Also add an onClick Listener that will update the applicable row/column and
        // refresh the ListView
        int cbidx = 0;
        for (CheckBox c: cblist) {
            c.setChecked(csr.getInt(cbidx + 1) == 1);
            c.setTag(new CBTag(entry_date,cbidx + 1));
            c.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    CBTag cbtag = (CBTag) view.getTag();
                    mDB.setDayEntryForOneCheckBox(
                            cbtag.getEntrydate(),
                            cbtag.getCheckBoxNumber(),
                            ((CheckBox)view).isChecked()
                    );
                    ((MainActivity) mContext).refreshDateEntryList();
                }
            });
            cbidx++;
        }
    }
}

对DatabaseHelper进行了一些更改,就像现在这样

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TB_DAYENTRIES = "day_entries";
    public static final String DAYENTRIES_COL_DATE = "_date";
    public static final String DAYENTRIES_COL_CB01 = "_cb01";
    public static final String DAYENTRIES_COL_CB02 = "_cb02";
    public static final String DAYENTRIES_COL_CB03 = "_cb03";
    public static final String DAYENTRIES_COL_CB04 = "_cb04";
    public static final String DAYENTRIES_COL_CB05 = "_cb05";
    public static final String DAYENTRIES_COL_CB06 = "_cb06";
    public static final String DAYENTRIES_COL_CB07 = "_cb07";
    public static final String DAYENTRIES_COL_CB08 = "_cb08";
    public static final String DAYENTRIES_COL_CB09 = "_cb09";
    public static final String DAYENTRIES_COL_CB10 = "_cb10";


    SQLiteDatabase mDB;
    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crt_tbl_sql = "CREATE TABLE IF NOT EXISTS " + TB_DAYENTRIES + "(" +
                DAYENTRIES_COL_DATE + " TEXT PRIMARY KEY NOT NULL," +
                DAYENTRIES_COL_CB01 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB02 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB03 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB04 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB05 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB06 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB07 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB08 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB09 + " INTEGER DEFAULT 0," +
                DAYENTRIES_COL_CB10 + " INTEGER DEFAULT 0" +
                ")";
        db.execSQL(crt_tbl_sql);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

    public long addNewDayEntry(String date) {
        ContentValues cv = new ContentValues();
        cv.put(DAYENTRIES_COL_DATE,date);
        return mDB.insert(TB_DAYENTRIES,null,cv);
    }

    public Cursor getDateEntryListAsCursor() {
        String[] columns = new String[]{"*,rowid AS _id"};
        return mDB.query(TB_DAYENTRIES,columns,null,null,null,null,null);
    }

    public int setDayEntryForOneCheckBox(String date, int checkbox, boolean status) {
        int rv = 0;
        String whereclause = DAYENTRIES_COL_DATE + "=?";
        String[] whereargs = new String[]{date};
        ContentValues cv = new ContentValues();
        int value = 0;
        if (status) {
            value = 1;
        }
        switch (checkbox) {
            case 1:
                cv.put(DAYENTRIES_COL_CB01,value);
                break;
            case 2:
                cv.put(DAYENTRIES_COL_CB02,value);
                break;
            case 3:
                cv.put(DAYENTRIES_COL_CB03,value);
                break;
            case 4:
                cv.put(DAYENTRIES_COL_CB04,value);
                break;
            case 5:
                cv.put(DAYENTRIES_COL_CB05,value);
                break;
            case 6:
                cv.put(DAYENTRIES_COL_CB06,value);
                break;
            case 7:
                cv.put(DAYENTRIES_COL_CB07,value);
                break;
            case 8:
                cv.put(DAYENTRIES_COL_CB08,value);
                break;
            case 9:
                cv.put(DAYENTRIES_COL_CB09,value);
                break;
            case 10:
                cv.put(DAYENTRIES_COL_CB10,value);
                break;
        }
        if (cv.size() == 1) {
            rv = mDB.update(TB_DAYENTRIES,cv,whereclause,whereargs);
        }
        return rv;
    }

    public boolean isDayEntryCheckboxSet(String date, int checkbox) {
        boolean rv = false;
        String whereclause = DAYENTRIES_COL_DATE + "=?";
        String[] whereargs = new String[]{date};
        if (checkbox < 1 || checkbox > 10) {
            return false;
        }
        Cursor csr = mDB.query(TB_DAYENTRIES,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            rv = csr.getInt(csr.getColumnIndex(getCheckboxColumnNameFromNumber(checkbox))) == 1;
        }
        csr.close();
        return rv;
    }

    private String getCheckboxColumnNameFromNumber(int checkbox) {
        switch (checkbox) {
            case 1:
                return DAYENTRIES_COL_CB01;
            case 2:
                return DAYENTRIES_COL_CB02;
            case 3:
                return DAYENTRIES_COL_CB03;
            case 4:
                return DAYENTRIES_COL_CB04;
            case 5:
                return DAYENTRIES_COL_CB05;
            case 6:
                return DAYENTRIES_COL_CB06;
            case 7:
                return DAYENTRIES_COL_CB07;
            case 8:
                return DAYENTRIES_COL_CB08;
            case 9:
                return DAYENTRIES_COL_CB09;
            case 10:
                return DAYENTRIES_COL_CB10;
        }
        return "";
    }
}

上次主要活动已更改,现在就像

public class MainActivity extends AppCompatActivity {

    DBHelper mDB;
    ListView mLV;
    CBListAdapter mCBLA;
    Cursor mCsr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDB  = new DBHelper(this);
        loadInitialData();
        mCsr = mDB.getDateEntryListAsCursor();
        mLV = this.findViewById(R.id.cblist);
        mCBLA = new CBListAdapter(this,mCsr);
        mLV.setAdapter(mCBLA);
    }

    protected void onResume() {
        super.onResume();
        refreshDateEntryList();
    }

    public void refreshDateEntryList() {
        mCsr = mDB.getDateEntryListAsCursor();
        mCBLA.swapCursor(mCsr);
    }

    private void loadInitialData() {
        long rowcount = DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(),DBHelper.TB_DAYENTRIES);
        if (rowcount > 0) return;
        String[] dates_to_add = new String[]{"2018-09-09","2018-09-10","2018-09-11"};
        for (String s: dates_to_add) {
            mDB.addNewDayEntry(s);
        }
        mDB.setDayEntryForOneCheckBox("2018-09-10",3,true);
        mDB.setDayEntryForOneCheckBox("2018-09-09",9,true);
    }
}
  • 这会将3行放入表中,同时还设置了一些要检查的行。

看起来像这样

选中复选框会同时更改复选框以及数据库中的数据。

enter image description here