質問するログイン新規登録

回答編集履歴

2

修正

2021/12/06 05:38

投稿

jimbe
jimbe

スコア13395

answer CHANGED
@@ -1,4 +1,4 @@
1
- 表示だけのことですので、データリストを弄る必要はありません。
1
+ 表示だけのことですので、リストデータを弄る必要はありません。
2
2
  complete と表示したい position のデータを求められたら complete のレイアウトデータを返すようにし、 それ以降のデータを求められたら position-1 の位置の実際のデータを返すだけです。
3
3
 
4
4
  ----
@@ -89,7 +89,7 @@
89
89
 
90
90
  fun add(todo: ToDo) {
91
91
  allData.add(todo)
92
- readAllData.value = allData
92
+ readAllData.value = allData //LiveData発火
93
93
  }
94
94
  }
95
95
  ```

1

コード追加

2021/12/06 05:38

投稿

jimbe
jimbe

スコア13395

answer CHANGED
@@ -1,2 +1,185 @@
1
1
  表示だけのことですので、データリストを弄る必要はありません。
2
- complete と表示したい position のデータを求められたら complete のレイアウトデータを返すようにし、 それ以降のデータを求められたら position-1 の位置の実際のデータを返すだけです。
2
+ complete と表示したい position のデータを求められたら complete のレイアウトデータを返すようにし、 それ以降のデータを求められたら position-1 の位置の実際のデータを返すだけです。
3
+
4
+ ----
5
+ Room は関係しなくても良さそうですので、表示部分だけテキトウに作って見ました。
6
+ (単に kotlin も Room も不慣れ(or ほぼ分からない)なだけですが...)
7
+ ```kotlin
8
+ package com.teratail.q372341
9
+
10
+ import android.os.Bundle
11
+ import android.view.LayoutInflater
12
+ import android.view.View
13
+ import android.view.ViewGroup
14
+ import android.widget.CheckBox
15
+ import android.widget.TextView
16
+ import androidx.appcompat.app.AppCompatActivity
17
+ import androidx.lifecycle.MutableLiveData
18
+ import androidx.lifecycle.ViewModel
19
+ import androidx.lifecycle.ViewModelProvider
20
+ import androidx.recyclerview.widget.LinearLayoutManager
21
+ import androidx.recyclerview.widget.RecyclerView
22
+
23
+ class MainActivity : AppCompatActivity() {
24
+ override fun onCreate(savedInstanceState: Bundle?) {
25
+ super.onCreate(savedInstanceState)
26
+ setContentView(R.layout.activity_main)
27
+
28
+ val adapter = ToDoAdapter()
29
+ val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
30
+ recyclerView.adapter = adapter
31
+ recyclerView.layoutManager = LinearLayoutManager(this)
32
+
33
+ val todoViewModel = ViewModelProvider(this).get(ToDoViewModel::class.java)
34
+ todoViewModel.readAllData.observe(this, { todo -> adapter.setData(todo) })
35
+
36
+ todoViewModel.add(ToDo(1, false, "todo 1"))
37
+ todoViewModel.add(ToDo(2, true, "todo 2"))
38
+ todoViewModel.add(ToDo(3, false, "todo 3"))
39
+ }
40
+ }
41
+
42
+ data class ToDo(
43
+ val id: Int,
44
+ val complete: Boolean,
45
+ val text: String
46
+ )
47
+
48
+ class ToDoAdapter: RecyclerView.Adapter<ToDoAdapter.ToDoViewHolder>() {
49
+ private var todoList = emptyList<ToDo>()
50
+ private val layouts = arrayOf(R.layout.recyclerview_item, R.layout.recyclerview_separator)
51
+
52
+ class ToDoViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
53
+ val checkBox: CheckBox?
54
+ val textView: TextView?
55
+ init {
56
+ checkBox = itemView.findViewById(R.id.checkBox)
57
+ textView = itemView.findViewById(R.id.textView)
58
+ }
59
+ }
60
+
61
+ override fun getItemViewType(position: Int) = if(position == separateIndex()) 1 else 0
62
+
63
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
64
+ ToDoViewHolder(LayoutInflater.from(parent.context).inflate(layouts[viewType], parent, false))
65
+
66
+ override fun getItemCount() = todoList.size + if(separateIndex() >= 0) 1 else 0
67
+
68
+ override fun onBindViewHolder(holder: ToDoViewHolder, position: Int) {
69
+ val separateIndex = separateIndex()
70
+ if(position == separateIndex) return //セパレータに表示するデータは無い
71
+
72
+ val pos = position - if(position > separateIndex) 1 else 0
73
+ val todo = todoList[pos]
74
+ holder.checkBox?.isChecked = todo.complete
75
+ holder.textView?.text = todo.text
76
+ }
77
+
78
+ fun setData(todoList: List<ToDo>) {
79
+ this.todoList = todoList.sortedWith(compareBy<ToDo> { it.complete }.thenBy { it.id })
80
+ notifyDataSetChanged()
81
+ }
82
+
83
+ private fun separateIndex() = todoList.indexOfFirst { it.complete }
84
+ }
85
+
86
+ class ToDoViewModel() : ViewModel() {
87
+ private var allData : MutableList<ToDo> = mutableListOf()
88
+ val readAllData = MutableLiveData<List<ToDo>>(allData)
89
+
90
+ fun add(todo: ToDo) {
91
+ allData.add(todo)
92
+ readAllData.value = allData
93
+ }
94
+ }
95
+ ```
96
+ res/layout/activity_main.xml
97
+ ```xml
98
+ <?xml version="1.0" encoding="utf-8"?>
99
+ <androidx.constraintlayout.widget.ConstraintLayout
100
+ xmlns:android="http://schemas.android.com/apk/res/android"
101
+ xmlns:app="http://schemas.android.com/apk/res-auto"
102
+ xmlns:tools="http://schemas.android.com/tools"
103
+ android:layout_width="match_parent"
104
+ android:layout_height="match_parent"
105
+ tools:context=".MainActivity">
106
+
107
+ <androidx.recyclerview.widget.RecyclerView
108
+ android:id="@+id/recyclerview"
109
+ android:layout_width="0dp"
110
+ android:layout_height="0dp"
111
+ app:layout_constraintBottom_toBottomOf="parent"
112
+ app:layout_constraintLeft_toLeftOf="parent"
113
+ app:layout_constraintRight_toRightOf="parent"
114
+ app:layout_constraintTop_toTopOf="parent" />
115
+
116
+ </androidx.constraintlayout.widget.ConstraintLayout>
117
+ ```
118
+ res/layout/recyclerview_item.xml
119
+ ```xml
120
+ <?xml version="1.0" encoding="utf-8"?>
121
+ <androidx.constraintlayout.widget.ConstraintLayout
122
+ xmlns:android="http://schemas.android.com/apk/res/android"
123
+ xmlns:app="http://schemas.android.com/apk/res-auto"
124
+ android:layout_width="match_parent"
125
+ android:layout_height="wrap_content">
126
+
127
+ <CheckBox
128
+ android:id="@+id/checkBox"
129
+ android:layout_width="wrap_content"
130
+ android:layout_height="wrap_content"
131
+ app:layout_constraintLeft_toLeftOf="parent"
132
+ app:layout_constraintTop_toTopOf="parent" />
133
+
134
+ <TextView
135
+ android:id="@+id/textView"
136
+ android:layout_width="0dp"
137
+ android:layout_height="wrap_content"
138
+ app:layout_constraintLeft_toRightOf="@id/checkBox"
139
+ app:layout_constraintRight_toRightOf="parent"
140
+ app:layout_constraintBaseline_toBaselineOf="@id/checkBox" />
141
+
142
+ </androidx.constraintlayout.widget.ConstraintLayout>
143
+ ```
144
+ res/layout/recyclerview_separator.xml
145
+ ```xml
146
+ <?xml version="1.0" encoding="utf-8"?>
147
+ <androidx.constraintlayout.widget.ConstraintLayout
148
+ xmlns:android="http://schemas.android.com/apk/res/android"
149
+ xmlns:app="http://schemas.android.com/apk/res-auto"
150
+ android:layout_width="match_parent"
151
+ android:layout_height="wrap_content">
152
+
153
+ <TextView
154
+ android:layout_width="0dp"
155
+ android:layout_height="wrap_content"
156
+ android:text="Complete"
157
+ android:layout_marginTop="5dp"
158
+ android:layout_marginBottom="10dp"
159
+ android:paddingLeft="5dp"
160
+ android:background="@drawable/upperline"
161
+ app:layout_constraintLeft_toLeftOf="parent"
162
+ app:layout_constraintRight_toRightOf="parent"
163
+ app:layout_constraintTop_toTopOf="parent" />
164
+
165
+ </androidx.constraintlayout.widget.ConstraintLayout>
166
+ ```
167
+ res/drawable/upperline.xml
168
+ ```xml
169
+ <?xml version="1.0" encoding="utf-8"?>
170
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
171
+
172
+ <item>
173
+ <shape android:shape="rectangle">
174
+ <solid android:color="#FFFFFF"/>
175
+ <stroke android:width="1dp" android:color="#AAAAAA" />
176
+ </shape>
177
+ </item>
178
+
179
+ <item android:top="1dp">
180
+ <shape android:shape="rectangle">
181
+ <solid android:color="#FFFFFF"/>
182
+ </shape>
183
+ </item>
184
+ </layer-list>
185
+ ```