1

私は、チェックボックスをチェックして値を更新すると、ビューが混乱したリサイクルビュー内でカーソルローダーを使用してsqliteデータベースを更新しています。いくつかの行もチェックされていますが、チェックされない値はまだ0です。これは、新しい行を挿入したときにも発生します。ここ更新データベースsqliteでコンテンツプロバイダを使用すると、recyclerviewのアイテムの位置が変更されるのはなぜですか?

iはデータベース

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); 
} 

}を更新しました私のMainActivityある

これは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

'onLoadFinished'では、リストから以前のデータを消去していないのはなぜですか? –

+0

RecyclerViewの[CheckBox]の重複している可能性がある項目のチェックが継続されています(https://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking-different-items) –

+0

@ cricket_007大丈夫です – mangkool

答えて

0

コードの次の部分では、else条件を指定していません。

if (isComplete == 1){ 
    holder.checkBox.setChecked(true); 
    holder.nameView.setState(isComplete); 
} 

RecyclerViewが古いビューを使用していますので、あなたには、チェックボックスをオフにするために、他の条件を処理する必要があります。

holder.checkBox.setChecked(isComplete == 1); 
holder.nameView.setState(isComplete); 

また、リストを再度作成する前に古いアイテムを消去する必要があります。

+0

ありがとう、それは今素晴らしいです。私は前のリストをクリアして、条件を追加した後に – mangkool

+0

それが動作する場合は、答えの横にあるチェックマークをクリックして、その答えを忘れずにマークすることを忘れないでください。 –

+0

'setChecked(isComplete == 1)'を実行すると、2行だけ必要です。 –

関連する問題