Ich aktualisiere meine SQLite-Datenbank mit Cursorloader innerhalb einer Recyclerview, wo ich es durch Ankreuzen der Checkbox, der Wert aktualisiert, aber irgendwie die Aussicht wurde ein Durcheinander. Einige Zeilen haben auch überprüft, aber der Wert ist immer 0, was nicht überprüft werden sollte. Dies geschieht auch, wenn ich eine neue Zeile einfüge.Warum Position Position in Recyclerview ändern, wenn Update-Datenbank sqlite Content-Provider verwenden?
hier mein MainActivity ist, wo ich die Datenbank aktualisiert
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);
}
}
dies ist der recyclerview Adapter
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;
}
}
wie diese zu lösen? Vielen Dank!
In 'onLoadFinished', warum löschen Sie keine vorherigen Daten aus der Liste? –
Mögliches Duplikat von [CheckBox in RecyclerView prüft weiterhin verschiedene Elemente] (https://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking- different- elements) –
@ cricket_007 okay, werde das versuchen – mangkool