diff --git a/app/build.gradle b/app/build.gradle index 07011c3..d3827dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,6 +29,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "androidx.recyclerview:recyclerview:1.1.0" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/app/src/main/java/tw/andyang/kotlinandroidworkshop/MainActivity.kt b/app/src/main/java/tw/andyang/kotlinandroidworkshop/MainActivity.kt index 9435d05..42fe1e7 100644 --- a/app/src/main/java/tw/andyang/kotlinandroidworkshop/MainActivity.kt +++ b/app/src/main/java/tw/andyang/kotlinandroidworkshop/MainActivity.kt @@ -1,11 +1,35 @@ package tw.andyang.kotlinandroidworkshop -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { + + private var todos = listOf() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + val adapter = TodoAdapter() + recyclerView.adapter = adapter + recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) + recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL)) + + todos = todos.toMutableList().apply { + add(Todo.Title(getString(R.string.todo_list_title))) + } + + adapter.submitList(todos) + + buttonAdd.setOnClickListener { + todos = todos.toMutableList().apply { + add(Todo.Item("world", false)) + } + adapter.submitList(todos) + } } } \ No newline at end of file diff --git a/app/src/main/java/tw/andyang/kotlinandroidworkshop/Todo.kt b/app/src/main/java/tw/andyang/kotlinandroidworkshop/Todo.kt new file mode 100644 index 0000000..d3a3984 --- /dev/null +++ b/app/src/main/java/tw/andyang/kotlinandroidworkshop/Todo.kt @@ -0,0 +1,14 @@ +package tw.andyang.kotlinandroidworkshop + +sealed class Todo(val viewType: Int) { + data class Title(val text: String) : Todo(TYPE_TITLE) + data class Item( + val memo: String, + val checked: Boolean + ) : Todo(TYPE_ITEM) + + companion object { + const val TYPE_TITLE = 0 + const val TYPE_ITEM = 1 + } +} diff --git a/app/src/main/java/tw/andyang/kotlinandroidworkshop/TodoAdapter.kt b/app/src/main/java/tw/andyang/kotlinandroidworkshop/TodoAdapter.kt new file mode 100644 index 0000000..928f01c --- /dev/null +++ b/app/src/main/java/tw/andyang/kotlinandroidworkshop/TodoAdapter.kt @@ -0,0 +1,62 @@ +package tw.andyang.kotlinandroidworkshop + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.appcompat.widget.AppCompatCheckBox +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.item_todo.view.* + +class TodoAdapter : ListAdapter( + object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Todo, newItem: Todo): Boolean { + return oldItem.viewType == newItem.viewType + } + + override fun areContentsTheSame(oldItem: Todo, newItem: Todo): Boolean { + return oldItem == newItem + } + } +) { + + override fun getItemViewType(position: Int): Int { + return getItem(position).viewType + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + Todo.TYPE_TITLE -> TodoTitleViewHolder(parent) + else -> TodoViewHolder(parent) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + when (val todo = getItem(position)) { + is Todo.Title -> (holder as TodoTitleViewHolder).bind(todo) + is Todo.Item -> (holder as TodoViewHolder).bind(todo) + } + } +} + +class TodoViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_todo, parent, false) +) { + + private val checkbox: AppCompatCheckBox = itemView.checkbox + + fun bind(todo: Todo.Item) { + checkbox.text = todo.memo + checkbox.isChecked = todo.checked + } + +} + +class TodoTitleViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_title, parent, false) +) { + fun bind(todo: Todo.Title) { + (itemView as AppCompatTextView).text = todo.text + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..c348834 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,15 +4,21 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipToPadding="false" tools:context=".MainActivity"> - + + + android:text="@string/add_todo" + app:layout_constraintBottom_toBottomOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_title.xml b/app/src/main/res/layout/item_title.xml new file mode 100644 index 0000000..b769358 --- /dev/null +++ b/app/src/main/res/layout/item_title.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_todo.xml b/app/src/main/res/layout/item_todo.xml new file mode 100644 index 0000000..fe33dd8 --- /dev/null +++ b/app/src/main/res/layout/item_todo.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c70dac..960ef27 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ KotlinAndroidWorkshop + 備忘錄 + 新增 \ No newline at end of file