登録したタスクを一覧表示するチェックリスト画面をRecyclerViewで作っています。
データベースはRealmを使っています。
現時点ではチェックを付けてもフラグメントの移動やアプリの再起動で消えてしまったり、新しいタスクがリストに追加されるとずれたりしてしまい、チェックボックスの値は全く保存されません。
なので、チェックボックスの値の変更を、データベースに保存・更新できるようにしたいです。
リスト画面のFragment.javaに下のコードを追加したらリスト画面を開いたとたんに落ちてしまうようになりました。
private CheckBox cb; //チェックボックス cb = view.findViewById(R.id.checkTask); cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { final Task task = new Task(); // Taskテーブルをインスタンス化 if(isChecked) { task.setCheck(true); } else { task.setCheck(false); } realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm bgRealm) { bgRealm.copyToRealmOrUpdate(task); } }); } });
はじめはonCheckedChangedの中身がいけないのかと思い、
下記のように中を空にしてやってみましたがやはり同様に落ちてしまいます。
private CheckBox cb; //チェックボックス cb = view.findViewById(R.id.checkTask); cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { } });
・リスト画面 TaskListFragment.java (チェックボックスの処理を含む全体のコード)
Java
1public class TaskListFragment extends Fragment { 2 private RecyclerView mRecyclerView; 3 private TaskAdapter adapter; 4 private Realm realm; 5 private FloatingActionButton fab; 6 7 private CheckBox cb; 8 9 @Override 10 public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 11 View view = inflater.inflate(R.layout.fragment_task_list, container, false); 12 13 //新規作成ボタン 14 fab = view.findViewById(R.id.newTask); 15 fab.setOnClickListener(new View.OnClickListener() { 16 @Override 17 public void onClick(View view) { 18 Intent intent = new Intent(getActivity(), com.j16390mf.memo.EditTask.class); 19 startActivity(intent); 20 } 21 }); 22 23 realm = Realm.getDefaultInstance(); 24 final RealmResults<Task> result = realm.where(Task.class).findAll().sort("id", Sort.DESCENDING); 25 adapter = new TaskAdapter(result); 26 27 mRecyclerView = view.findViewById(R.id.tasklist); 28 mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 29 mRecyclerView.setAdapter(adapter); 30 mRecyclerView.setHasFixedSize(true); 31 mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL)); 32 33 //チェックボックス 34 cb = view.findViewById(R.id.checkTask); 35 cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 36 @Override 37 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 38 final Task task = new Task(); // Taskテーブルをインスタンス化 39 if(isChecked) { 40 task.setCheck(true); 41 } else { 42 task.setCheck(false); 43 } 44 realm.executeTransactionAsync(new Realm.Transaction() { 45 @Override 46 public void execute(Realm bgRealm) { 47 bgRealm.copyToRealmOrUpdate(task); 48 } 49 }); 50 } 51 }); 52 53 return view; 54 } 55 56 @Override 57 public void onDestroy() { 58 super.onDestroy(); 59 mRecyclerView.setAdapter(null); 60 realm.close(); 61 } 62}
自分で気になっているところは、
チェックボックスのViewがきちんと取得できているのかという点です。
cb = view.findViewById(R.id.checkTask);
checkTask というIDのViewは、リスト1行分のレイアウトの中にあります。
それをAdapter経由でリスト画面に表示させています。たぶん
リスト1行分のレイアウトは、リスト画面でインフレートしてるわけじゃないので、checkTaskが取得できてるのかよく分かりません。
アプリが落ちてしまう原因とは関係ないかもしれませんが。
図の説明で逆に分かりづらかったら申し訳ないです。
・追加したチェックボックスの処理のコードのどこがだめっぽいか
・チェックボックスのViewを含むレイアウトはリスト画面でインフレートされてないが、ちゃんと取得できてるのかどうか
ご回答お待ちしております。
・listitem_tasklist.xml RecyclerViewのリスト1行分のレイアウト
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="8dp" android:paddingEnd="8dp" xmlns:app="http://schemas.android.com/apk/res-auto"> <CheckBox android:id="@+id/checkTask" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <TextView android:id="@+id/taskTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@id/checkTask" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="@string/taskTitle" android:textSize="20sp"/> <TextView android:id="@+id/taskId" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="@id/taskTitle" app:layout_constraintTop_toBottomOf="@id/taskTitle" android:text="@string/taskId" android:textSize="12sp"/> <TextView android:id="@+id/closingDate" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/taskTitle" android:text="@string/closingDate" android:textSize="12sp"/> </android.support.constraint.ConstraintLayout>
・TaskAdapter.java RecyclerViewのアダプタ
public class TaskAdapter extends RealmRecyclerViewAdapter<Task, TaskAdapter.TaskViewHolder> { private OrderedRealmCollection<Task> tDataset; TaskAdapter(OrderedRealmCollection<Task> taskDataset) { super(taskDataset, true); this.tDataset = taskDataset; setHasStableIds(true); } @Override public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_tasklist, parent, false); return new TaskViewHolder(view); } @Override public void onBindViewHolder(TaskViewHolder holder, int position) { final Task obj = getItem(position); holder.name.setText(obj.getName()); holder.check.setChecked(obj.getCheck()); holder.id.setText(obj.getId()); } @Override public int getItemCount() { return tDataset.size(); } static class TaskViewHolder extends RecyclerView.ViewHolder { TextView name; CheckBox check; TextView id; TaskViewHolder(View view) { super(view); name = view.findViewById(R.id.taskTitle); check = view.findViewById(R.id.checkTask); id = view.findViewById(R.id.taskId); } } }
・Task.java Taskテーブル
public class Task extends RealmObject { @PrimaryKey private String id; private String name; private boolean check; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean getCheck() { return check;} public void setCheck(boolean check) { this.check = check;} }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/04 12:54
2019/11/04 15:26