使用 SQLite 数据库保存 CheckBox 状态
Posted
技术标签:
【中文标题】使用 SQLite 数据库保存 CheckBox 状态【英文标题】:Saving CheckBox state with SQLite Database 【发布时间】:2018-08-17 13:30:10 【问题描述】:我正在构建一个列表应用程序,它使用 SQLite 数据库来保存列表项。列表项由 UUID、名称和布尔值组成,以确定其是否已解决(数据库将其存储为 int)。我注意到的是,当用户关闭任务并添加新任务时,列表会重新加载,以便现在取消选中已检查的任务。此外,当应用程序重新启动时,列表会重新加载,因此所有已选中的任务都将变为未选中状态。
现在我一直在思考想法,到目前为止,我所做的是在我的 TaskAdapter 类中的 onBindViewHolder() 方法中,我调用 setOnCheckedChangedListener() 以便在用户检查任务时启动 toast。我觉得我应该在这里做一些事情来更新数据库中的特定任务,但我不知道如何。
附加说明:我正在使用一个单例类,其中包含所有数据库方法,例如添加任务、更新任务和从数据库中检索所有任务。
ListFragment.java
public class ListFragment extends Fragment implements AddTaskDialog.addTask
private static final String ADD_TASK_TAG = "ADD_TASK_DIALOG";
private RecyclerView mRecyclerView;
private TaskAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list, container, false);
mRecyclerView = view.findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(layoutManager);
updateUI();
return view;
private void updateUI()
List<Task> tasks = TaskLab.getTaskLab(getContext()).getTaskList();
if(mAdapter == null)
mAdapter = new TaskAdapter(tasks);
mRecyclerView.setAdapter(mAdapter);
else
mAdapter.setTaskList(tasks);
mAdapter.notifyDataSetChanged();
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.toolbar_layout,menu);
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case R.id.add_task_button:
// Launch a dialog.
AddTaskDialog dialog = new AddTaskDialog();
FragmentManager manager = getFragmentManager();
dialog.setTargetFragment(ListFragment.this,1);
dialog.show(manager,ADD_TASK_TAG);
return true;
default:
return super.onOptionsItemSelected(item);
// Part of the addTask interface created in AddTaskDialog
@Override
public void addTask(String taskName)
Task task = new Task();
task.setName(taskName);
TaskLab.getTaskLab(getContext()).addTask(task);
updateUI();
TaskAdapter.java
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskHolder>
private List<Task> mTaskList;
public TaskAdapter(List<Task> tasks)
mTaskList = tasks;
@Override
public TaskAdapter.TaskHolder onCreateViewHolder(ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_layout,parent,false);
return new TaskHolder(view);
@Override
public void onBindViewHolder(TaskAdapter.TaskHolder holder, int position)
Task task = mTaskList.get(position);
holder.bindData(task);
holder.mTaskCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked)
if(isChecked)
Toast.makeText(compoundButton.getContext(),"Task Solved!",Toast.LENGTH_SHORT).show();
);
@Override
public int getItemCount()
return mTaskList.size();
public void setTaskList(List<Task> tasks)
mTaskList = tasks;
public class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener
private TextView mTaskName;
private CheckBox mTaskCheckBox;
public TaskHolder(View itemView)
super(itemView);
mTaskName = itemView.findViewById(R.id.task_name);
mTaskCheckBox = itemView.findViewById(R.id.task_checkbox);
private void bindData(Task task)
mTaskName.setText(task.getName());
mTaskCheckBox.setChecked(task.isSolved());
@Override
public void onClick(View view)
TaskLab.java(单例类)
public class TaskLab
private static TaskLab sTaskLab;
private Context mContext;
private SQLiteDatabase mDatabase;
private TaskLab(Context context)
mContext = context.getApplicationContext();
mDatabase = new TaskBaseHelper(mContext).getWritableDatabase();
public static TaskLab getTaskLab(Context context)
if(sTaskLab == null)
sTaskLab = new TaskLab(context);
return sTaskLab;
// Add DataBase operation method here.
private ContentValues getContentValues(Task task)
ContentValues values = new ContentValues();
values.put(TaskTable.Cols.UUID, task.getId().toString());
values.put(TaskTable.Cols.NAME, task.getName());
values.put(TaskTable.Cols.SOLVED, task.isSolved() ? 1 : 0);
return values;
public void addTask(Task task)
ContentValues values = getContentValues(task);
mDatabase.insert(TaskTable.TABLE_NAME,null,values);
// Don't really understand this method
public void updateTask(Task task)
String uuidString = task.getId().toString();
ContentValues values = getContentValues(task);
mDatabase.update(TaskTable.TABLE_NAME,values, TaskTable.Cols.UUID + " = ?",
new String[] uuidString);
public TaskCursorWrapper queryTasks(String whereClause, String[] whereArgs)
Cursor cursor = mDatabase.query(TaskTable.TABLE_NAME,null,whereClause,whereArgs,null,null,null);
return new TaskCursorWrapper(cursor);
public List<Task> getTaskList()
List<Task> taskList = new ArrayList<>();
TaskCursorWrapper cursor = queryTasks(null,null);
try
cursor.moveToFirst();
while(!cursor.isAfterLast())
Task task = cursor.getTask();
taskList.add(task);
cursor.moveToNext();
finally
cursor.close();
return taskList;
【问题讨论】:
您可以在模型类中使用任何布尔参数。并在此布尔参数中设置复选框状态。您可以将该参数值保存在数据库中。当您想从数据库中获取值时,只需检查布尔值并在复选框中设置该布尔值。 @HardikVaghasiya 我的模型类中确实有一个布尔参数。只是我无法从适配器类访问数据库,因为我的数据库存储在 TaskLab(单例类)中。如果我能以某种方式访问该数据库,那么我可以从 TaskLab 调用 updateTask() 方法,这样就可以完成工作。 【参考方案1】:在adapter中,当你使用onclick时,当前项目会更新,但是在滚动时点击复选框的位置会不匹配。因为适配器只考虑您从您的代码中写入的位置。所以请使用任何 getter/setter 来避免这个问题。
【讨论】:
以上是关于使用 SQLite 数据库保存 CheckBox 状态的主要内容,如果未能解决你的问题,请参考以下文章