Skip to content

Commit 66d7479

Browse files
committed
implement to get task
1 parent 60804d5 commit 66d7479

File tree

12 files changed

+210
-25
lines changed

12 files changed

+210
-25
lines changed

app/build.gradle

+7-6
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,10 @@ android {
5555
dependencies {
5656
implementation fileTree(dir: "libs", include: ["*.jar"])
5757
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
58-
implementation 'androidx.core:core-ktx:1.3.1'
58+
implementation 'androidx.core:core-ktx:1.3.2'
5959
implementation 'androidx.appcompat:appcompat:1.2.0'
60-
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
61-
testImplementation 'junit:junit:4.12'
62-
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
63-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
60+
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
61+
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
6462
implementation 'com.google.android.material:material:1.2.1'
6563

6664
// dagger
@@ -72,13 +70,15 @@ dependencies {
7270
def coroutine_version = "1.3.9"
7371
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"
7472
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutine_version"
73+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutine_version"
7574

7675
// deploy gate
7776
implementation 'com.deploygate:sdk:4.1.0'
7877

7978
// Firebase
8079
implementation 'com.google.firebase:firebase-analytics:17.5.0'
8180
implementation 'com.google.firebase:firebase-auth:19.4.0'
81+
implementation 'com.google.firebase:firebase-firestore:21.7.0'
8282
implementation 'com.firebaseui:firebase-ui-auth:6.2.0'
8383

8484
// test
@@ -88,8 +88,9 @@ dependencies {
8888
testImplementation 'org.mockito:mockito-core:3.3.3'
8989
testImplementation 'org.mockito:mockito-android:3.3.3'
9090
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
91-
androidTestImplementation 'androidx.annotation:annotation:1.1.0'
9291
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
92+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
93+
androidTestImplementation 'androidx.annotation:annotation:1.1.0'
9394

9495
// other
9596
implementation 'com.jakewharton.timber:timber:4.7.1'

app/src/main/java/io/github/mrtry/todolist/app/todo/ui/ToDoActivity.kt

+9
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import android.content.Intent
55
import android.os.Bundle
66
import androidx.appcompat.app.AppCompatActivity
77
import androidx.databinding.DataBindingUtil
8+
import androidx.recyclerview.widget.LinearLayoutManager
89
import io.github.mrtry.todolist.MainApplication
910
import io.github.mrtry.todolist.R
11+
import io.github.mrtry.todolist.app.todo.ui.adapter.ToDoAdapter
1012
import io.github.mrtry.todolist.app.todo.ui.navigator.ToDoNavigator
1113
import io.github.mrtry.todolist.app.todo.viewmodel.ToDoViewModel
1214
import io.github.mrtry.todolist.databinding.ActivityToDoBinding
@@ -50,6 +52,13 @@ class ToDoActivity : AppCompatActivity(), Injectable<ToDoComponent>, Bindable<Ac
5052
viewModel = this@ToDoActivity.viewModel.taskViewModel
5153
lifecycleOwner = this@ToDoActivity
5254
}
55+
56+
with(list) {
57+
adapter = ToDoAdapter(this@ToDoActivity, this@ToDoActivity.viewModel.items, this@ToDoActivity)
58+
layoutManager = LinearLayoutManager(this@ToDoActivity)
59+
}
5360
}
61+
62+
viewModel.load()
5463
}
5564
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.github.mrtry.todolist.app.todo.ui.adapter
2+
3+
import android.content.Context
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import androidx.databinding.DataBindingUtil
8+
import androidx.databinding.ObservableList
9+
import androidx.lifecycle.LifecycleOwner
10+
import androidx.recyclerview.widget.RecyclerView
11+
import io.github.mrtry.todolist.R
12+
import io.github.mrtry.todolist.app.todo.viewmodel.ToDoListItemViewModel
13+
import io.github.mrtry.todolist.databinding.ListItemToDoBinding
14+
import io.github.mrtry.todolist.misc.extension.addOnListChangedSimpleCallback
15+
16+
class ToDoAdapter(
17+
context: Context,
18+
private val items: ObservableList<ToDoListItemViewModel>,
19+
private val lifecycleOwner: LifecycleOwner
20+
) : RecyclerView.Adapter<ToDoAdapter.ViewHolder>() {
21+
private val inflater = LayoutInflater.from(context)
22+
23+
init {
24+
items.addOnListChangedSimpleCallback {
25+
notifyDataSetChanged()
26+
}
27+
}
28+
29+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
30+
ViewHolder(inflater.inflate(R.layout.list_item_to_do, parent, false))
31+
32+
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
33+
val item = getItem(position)
34+
35+
with(holder.binding) {
36+
lifecycleOwner = this@ToDoAdapter.lifecycleOwner
37+
viewModel = item
38+
executePendingBindings()
39+
}
40+
}
41+
42+
override fun getItemCount(): Int = items.size
43+
44+
private fun getItem(position: Int): ToDoListItemViewModel = items[position]
45+
46+
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
47+
val binding: ListItemToDoBinding = DataBindingUtil.bind(itemView)!!
48+
}
49+
50+
}

app/src/main/java/io/github/mrtry/todolist/app/todo/viewmodel/TaskViewModel.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class TaskViewModel
3838
if (e is CancellationException) return@launch
3939

4040
Timber.e(e)
41-
navigator.showSnackBar(R.string.to_do_activity_error_failed)
41+
navigator.showSnackBar(R.string.to_do_activity_error_add_task_failed)
42+
} finally {
43+
isSaving.value = false
4244
}
43-
44-
isSaving.value = false
4545
}
4646
}
4747
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
package io.github.mrtry.todolist.app.todo.viewmodel
22

3-
class ToDoListItemViewModel {
4-
}
3+
import io.github.mrtry.todolist.todo.entity.ToDo
4+
5+
data class ToDoListItemViewModel(
6+
val task: ToDo
7+
)
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,61 @@
11
package io.github.mrtry.todolist.app.todo.viewmodel
22

3+
import androidx.databinding.ObservableArrayList
4+
import androidx.databinding.ObservableList
5+
import androidx.lifecycle.MutableLiveData
6+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
7+
import io.github.mrtry.todolist.R
8+
import io.github.mrtry.todolist.app.todo.ui.navigator.ToDoNavigator
9+
import io.github.mrtry.todolist.app.todo.viewmodel.converter.ToDoListItemViewModelConverter
310
import io.github.mrtry.todolist.di.scope.ActivityScope
411
import io.github.mrtry.todolist.misc.ui.viewmodel.ToolbarViewModel
12+
import io.github.mrtry.todolist.todo.domainservice.ToDoDomainService
13+
import kotlinx.coroutines.CancellationException
14+
import kotlinx.coroutines.CoroutineScope
15+
import kotlinx.coroutines.launch
16+
import timber.log.Timber
517
import javax.inject.Inject
618

719
@ActivityScope
820
class ToDoViewModel
921
@Inject constructor(
1022
val toolbarViewModel: ToolbarViewModel,
11-
val taskViewModel: TaskViewModel
12-
) {
23+
val taskViewModel: TaskViewModel,
24+
private val navigator: ToDoNavigator,
25+
private val toDoDomainService: ToDoDomainService,
26+
private val converter: ToDoListItemViewModelConverter,
27+
private val coroutineScope: CoroutineScope
28+
) : SwipeRefreshLayout.OnRefreshListener {
29+
val isRefreshing: MutableLiveData<Boolean> = MutableLiveData(false)
30+
31+
val items: ObservableList<ToDoListItemViewModel> = ObservableArrayList()
32+
33+
override fun onRefresh() {
34+
isRefreshing.value = true
35+
items.clear()
36+
load()
37+
}
38+
39+
fun load() {
40+
coroutineScope.launch {
41+
try {
42+
toDoDomainService.get().also { todo ->
43+
todo.map {
44+
items.add(
45+
converter.convert(it)
46+
)
47+
}
48+
}
49+
} catch (e: Exception) {
50+
if (e is CancellationException) return@launch
51+
52+
Timber.e(e)
53+
navigator.showSnackBar(R.string.to_do_activity_error_get_task_failed)
54+
} finally {
55+
isRefreshing.value = false
56+
}
57+
}
58+
}
59+
60+
1361
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
package io.github.mrtry.todolist.app.todo.viewmodel.converter
22

3-
class ToDoListItemViewModelConverter {
3+
import io.github.mrtry.todolist.app.todo.viewmodel.ToDoListItemViewModel
4+
import io.github.mrtry.todolist.di.scope.ActivityScope
5+
import io.github.mrtry.todolist.todo.entity.ToDo
6+
import javax.inject.Inject
7+
8+
@ActivityScope
9+
class ToDoListItemViewModelConverter
10+
@Inject constructor() {
11+
fun convert(entity: ToDo): ToDoListItemViewModel =
12+
ToDoListItemViewModel(
13+
entity
14+
)
415
}

app/src/main/java/io/github/mrtry/todolist/misc/extension/ObservableListEx.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.mrtry.todolist.misc.ui.extension
1+
package io.github.mrtry.todolist.misc.extension
22

33
import androidx.databinding.ObservableList
44

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
package io.github.mrtry.todolist.misc.ui.binding
22

3+
import androidx.databinding.BindingAdapter
4+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
5+
6+
@BindingAdapter("onRefresh")
7+
fun SwipeRefreshLayout.setOnRefreshListener(listener: SwipeRefreshLayout.OnRefreshListener) {
8+
setOnRefreshListener(listener)
9+
}

app/src/main/res/layout/activity_to_do.xml

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
2+
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
34

45
<data>
56

@@ -8,7 +9,8 @@
89
type="io.github.mrtry.todolist.app.todo.viewmodel.ToDoViewModel" />
910
</data>
1011

11-
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
12+
13+
<androidx.constraintlayout.widget.ConstraintLayout
1214
android:layout_width="match_parent"
1315
android:layout_height="match_parent">
1416

@@ -27,11 +29,25 @@
2729
layout="@layout/banner_add_task"
2830
app:layout_constraintTop_toBottomOf="@id/toolbar" />
2931

30-
<androidx.recyclerview.widget.RecyclerView
32+
<View
33+
android:id="@+id/divider"
3134
android:layout_width="match_parent"
32-
android:layout_height="0dp"
35+
android:layout_height="@dimen/list_item_divider_height"
3336
app:layout_constraintTop_toBottomOf="@id/banner_add_task"
34-
app:layout_constraintBottom_toBottomOf="parent" />
37+
android:background="?android:attr/dividerVertical" />
38+
39+
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
40+
android:layout_width="match_parent"
41+
android:layout_height="0dp"
42+
app:layout_constraintTop_toBottomOf="@id/divider"
43+
app:layout_constraintBottom_toBottomOf="parent"
44+
app:onRefresh="@{viewModel}"
45+
app:refreshing="@{viewModel.isRefreshing}">
3546

47+
<androidx.recyclerview.widget.RecyclerView
48+
android:id="@+id/list"
49+
android:layout_width="match_parent"
50+
android:layout_height="match_parent" />
51+
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
3652
</androidx.constraintlayout.widget.ConstraintLayout>
3753
</layout>
+43-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,45 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<androidx.constraintlayout.widget.ConstraintLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
4-
android:layout_height="match_parent">
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto">
54

6-
</androidx.constraintlayout.widget.ConstraintLayout>
5+
<data>
6+
7+
<variable
8+
name="viewModel"
9+
type="io.github.mrtry.todolist.app.todo.viewmodel.ToDoListItemViewModel" />
10+
</data>
11+
12+
<androidx.constraintlayout.widget.ConstraintLayout
13+
android:layout_width="match_parent"
14+
android:layout_height="@dimen/list_item_container_height_one_line">
15+
16+
<com.google.android.material.checkbox.MaterialCheckBox
17+
android:id="@+id/checkbox"
18+
android:layout_width="wrap_content"
19+
android:layout_height="wrap_content"
20+
android:layout_marginStart="@dimen/list_item_check_box_margin_start"
21+
app:layout_constraintStart_toStartOf="parent"
22+
app:layout_constraintTop_toTopOf="parent"
23+
app:layout_constraintBottom_toBottomOf="parent" />
24+
25+
<TextView
26+
android:id="@+id/title"
27+
android:layout_width="0dp"
28+
android:layout_height="wrap_content"
29+
android:layout_marginHorizontal="@dimen/list_item_margin_horizontal"
30+
app:layout_constraintStart_toEndOf="@id/checkbox"
31+
app:layout_constraintEnd_toEndOf="parent"
32+
app:layout_constraintTop_toTopOf="parent"
33+
app:layout_constraintBottom_toBottomOf="parent"
34+
android:text="@{viewModel.task.title}"
35+
android:ellipsize="end"
36+
android:maxLines="1" />
37+
38+
<View
39+
android:id="@+id/divider"
40+
android:layout_width="match_parent"
41+
android:layout_height="@dimen/list_item_divider_height"
42+
app:layout_constraintBottom_toBottomOf="parent"
43+
android:background="?android:attr/dividerVertical" />
44+
</androidx.constraintlayout.widget.ConstraintLayout>
45+
</layout>

app/src/main/res/values/strings.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<resources>
22
<string name="app_name">ToDoList</string>
3-
<string name="to_do_activity_error_failed">登録に失敗しました。再度お試しください。</string>
3+
<string name="to_do_activity_error_add_task_failed">登録に失敗しました。再度お試しください。</string>
4+
<string name="to_do_activity_error_get_task_failed">取得に失敗しました。再度お試しください。</string>
45
</resources>

0 commit comments

Comments
 (0)