我在recyclelerview中使用cursorloader更新我的sqlite数据库,我通过选中复选框来更新我的sqlite数据库,更新了值,但不知何故,视图变得一团糟。某些行也已检查但值仍为0,应该不检查。当我插入新行时也会发生这种情况。
这是我更新数据库的主要活动
public class MainActivity extends AppCompatActivity implements
TaskAdapter.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>{
private TaskAdapter mAdapter;
private FloatingActionButton floatingActionButton;
private ArrayList<Task> task = new ArrayList<>();
private static final int TASKS_LOADER_ID = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mAdapter = new TaskAdapter(this);
mAdapter.setOnItemClickListener(this);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(mAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
/* Click events in floating action button */
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), AddTaskActivity.class);
startActivity(intent);
}
});
//initialize the loader
getSupportLoaderManager().initLoader(TASKS_LOADER_ID, null, this);
}
@Override
protected void onResume() {
super.onResume();
Log.v("dipanggil", "dipanggil jka");
// re-queries for all tasks
getSupportLoaderManager().restartLoader(TASKS_LOADER_ID, null, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
/* Click events in RecyclerView items */
@Override
public void onItemClick(View v, int position) {
//TODO: Handle list item click event
Intent intent = new Intent(this, TaskDetailActivity.class);
/*b.putLong("ID", task.get(position).getId());
b.putString("DESCRIPTION", task.get(position).getDescription());
b.putInt("PRIORITY", task.get(position).getPriority());
b.putInt("COMPLETE", task.get(position).getComplete());
b.putLong("DUEDATE", task.get(position).getDueDateMillis());*/
intent.putExtra("ID", String.valueOf(task.get(position).getId()));
startActivity(intent);
Log.v("testti", ""+v.getTag()+" apakah sama "+task.get(position).getId());
}
/* Click events on RecyclerView item checkboxes */
@Override
public void onItemToggled(boolean active, int position) {
//TODO: Handle task item checkbox event
ContentValues values = new ContentValues();
String stringId = String.valueOf(task.get(position).getId());
Log.v("test = ", ""+task.get(position).getId());
Uri uri = DatabaseContract.CONTENT_URI;
uri = uri.buildUpon().appendPath(stringId).build();
if(active) {
Log.v("test","tersentuh");
//values.put(DatabaseContract.TaskColumns.IS_COMPLETE, 1);
values.put(DatabaseContract.TaskColumns._ID, task.get(position).getId());
values.put(DatabaseContract.TaskColumns.DESCRIPTION, task.get(position).getDescription());
values.put(DatabaseContract.TaskColumns.IS_PRIORITY, task.get(position).getPriority());
values.put(DatabaseContract.TaskColumns.IS_COMPLETE, 1);
values.put(DatabaseContract.TaskColumns.DUE_DATE, task.get(position).getDueDateMillis());
getContentResolver().update(uri,
values,
null,
null);
}else{
Log.v("test","tidak tersentuh");
values.put(DatabaseContract.TaskColumns._ID, task.get(position).getId());
values.put(DatabaseContract.TaskColumns.DESCRIPTION, task.get(position).getDescription());
values.put(DatabaseContract.TaskColumns.IS_PRIORITY, task.get(position).getPriority());
values.put(DatabaseContract.TaskColumns.IS_COMPLETE, 0);
values.put(DatabaseContract.TaskColumns.DUE_DATE, task.get(position).getDueDateMillis());
getContentResolver().update(uri,
values,
null,
null);
}
// re-queries for all tasks
//mAdapter.notifyDataSetChanged();
getSupportLoaderManager().restartLoader(TASKS_LOADER_ID, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new AsyncTaskLoader<Cursor>(this) {
// Initialize a Cursor, this will hold all the task data
Cursor mTaskData = null;
// onStartLoading() is called when a loader first starts loading data
@Override
protected void onStartLoading() {
if (mTaskData != null) {
// Delivers any previously loaded data immediately
deliverResult(mTaskData);
} else {
// Force a new load
forceLoad();
}
}
@Override
public Cursor loadInBackground() {
try {
return getContentResolver().query(DatabaseContract.CONTENT_URI,
null,
null,
null,
DatabaseContract.DEFAULT_SORT);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void deliverResult(Cursor data) {
mTaskData = data;
super.deliverResult(data);
}
};
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
while(data.moveToNext()){
long id = data.getLong(data.getColumnIndex(DatabaseContract.TaskColumns._ID));
String description = data.getString(data.getColumnIndex(DatabaseContract.TaskColumns.DESCRIPTION));
long date = data.getLong(data.getColumnIndex(DatabaseContract.TaskColumns.DUE_DATE));
int priority = data.getInt(data.getColumnIndex(DatabaseContract.TaskColumns.IS_PRIORITY));
int complete = data.getInt(data.getColumnIndex(DatabaseContract.TaskColumns.IS_COMPLETE));
try{
Task tasks = new Task(data);
task.add(tasks);
}catch (Exception e){
e.printStackTrace();
}
}
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
这是recyclerview适配器
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskHolder> {
/* Callback for list item click events */
public interface OnItemClickListener {
void onItemClick(View v, int position);
void onItemToggled(boolean active, int position);
}
/* ViewHolder for each task item */
public class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TaskTitleView nameView;
public TextView dateView;
public ImageView priorityView;
public CheckBox checkBox;
public TaskHolder(View itemView) {
super(itemView);
nameView = (TaskTitleView) itemView.findViewById(R.id.text_description);
dateView = (TextView) itemView.findViewById(R.id.text_date);
priorityView = (ImageView) itemView.findViewById(R.id.priority);
checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
itemView.setOnClickListener(this);
checkBox.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == checkBox) {
completionToggled(this);
} else {
postItemClick(this);
}
}
}
private Cursor mCursor;
private OnItemClickListener mOnItemClickListener;
private Context mContext;
public TaskAdapter(Context mContext) {
this.mContext = mContext;
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
private void completionToggled(TaskHolder holder) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemToggled(holder.checkBox.isChecked(), holder.getAdapterPosition());
}
}
private void postItemClick(TaskHolder holder) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(holder.itemView, holder.getAdapterPosition());
}
}
@Override
public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.list_item_task, parent, false);
return new TaskHolder(itemView);
}
@Override
public void onBindViewHolder(TaskHolder holder, int position) {
//TODO: Bind the task data to the views
// Indices for the _id, description, and priority columns
int idIndex = mCursor.getColumnIndex(DatabaseContract.TaskColumns._ID);
int descriptionIndex = mCursor.getColumnIndex(DatabaseContract.TaskColumns.DESCRIPTION);
int isCompleteIndex = mCursor.getColumnIndex(DatabaseContract.TaskColumns.IS_COMPLETE);
int isPriorityIndex = mCursor.getColumnIndex(DatabaseContract.TaskColumns.IS_PRIORITY);
int dueDateIndex = mCursor.getColumnIndex(DatabaseContract.TaskColumns.DUE_DATE);
//move cursor to wanted data
mCursor.moveToPosition(position);
// Determine the values of the wanted data
final int id = mCursor.getInt(idIndex);
String description = mCursor.getString(descriptionIndex);
int isComplete = mCursor.getInt(isCompleteIndex);
int isPrior = mCursor.getInt(isPriorityIndex);
long dueDate = mCursor.getLong(dueDateIndex);
Log.v("adapter", " "+DateUtils.getRelativeTimeSpanString(mContext, dueDate)+" "+dueDate);
CharSequence date = DateUtils.getRelativeTimeSpanString(mContext, dueDate);
holder.itemView.setTag(id);
//determine whether to show date or not
if(dueDate != Long.MAX_VALUE){
holder.dateView.setVisibility(View.VISIBLE);
holder.dateView.setText(date);
}else{
holder.dateView.setVisibility(View.GONE);
}
//determine the priority icon
if(isPrior == 0){
holder.priorityView.setImageResource(R.drawable.ic_not_priority);
}else{
holder.priorityView.setImageResource(R.drawable.ic_priority);
}
//determine the text color and description
holder.nameView.setText(description);
holder.nameView.setState(isComplete);
if(isComplete == 1){
holder.checkBox.setChecked(true);
holder.nameView.setState(isComplete);
}
//to chek if due date has passed or not
Calendar now = Calendar.getInstance();
Calendar tasksDate = Calendar.getInstance();
tasksDate.setTimeInMillis(dueDate);
int result = now.compareTo(tasksDate);
if(result >= 0){
holder.nameView.setState(2);
}
else if(result < 0){
holder.nameView.setState(0);
}
}
@Override
public int getItemCount() {
return (mCursor != null) ? mCursor.getCount() : 0;
}
/**
* Retrieve a {@link Task} for the data at the given position.
*
* @param position Adapter item position.
*
* @return A new {@link Task} filled with the position's attributes.
*/
public Task getItem(int position) {
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("Invalid item position requested");
}
return new Task(mCursor);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
public Cursor swapCursor(Cursor cursor) {
if (mCursor == cursor) {
return null; // bc nothing has changed
}
Cursor temp = mCursor;
this.mCursor = cursor; // new cursor value assigned
//check if this is a valid cursor, then update the cursor
if (cursor != null) {
this.notifyDataSetChanged();
}
return temp;
}
}
如何解决这个问题?谢谢!
答案 0 :(得分:0)
在您的代码的以下部分中,您还没有提供其他条件。
if (isComplete == 1){
holder.checkBox.setChecked(true);
holder.nameView.setState(isComplete);
}
您应该处理其他条件以取消选中该复选框,因为RecyclerView
使用旧视图。
holder.checkBox.setChecked(isComplete == 1);
holder.nameView.setState(isComplete);
此外,您应该在重新填充列表之前清除旧项目。