1
+ package io.github.mrtry.todolist.app.todo.ui
2
+
3
+ import android.os.Bundle
4
+ import android.view.KeyEvent
5
+ import android.view.LayoutInflater
6
+ import android.view.View
7
+ import android.view.ViewGroup
8
+ import androidx.activity.addCallback
9
+ import androidx.fragment.app.DialogFragment
10
+ import androidx.fragment.app.Fragment
11
+ import io.github.mrtry.todolist.R
12
+ import io.github.mrtry.todolist.app.todo.ui.navigator.EditTaskNavigator
13
+ import io.github.mrtry.todolist.app.todo.viewmodel.EditTaskViewModel
14
+ import io.github.mrtry.todolist.databinding.FragmentEditTaskBinding
15
+ import io.github.mrtry.todolist.di.Injectable
16
+ import io.github.mrtry.todolist.di.component.EditTaskComponent
17
+ import io.github.mrtry.todolist.di.component.ToDoComponent
18
+ import io.github.mrtry.todolist.di.module.FragmentModule
19
+ import io.github.mrtry.todolist.di.scope.FragmentScope
20
+ import io.github.mrtry.todolist.di.utils.ComponentUtils
21
+ import io.github.mrtry.todolist.misc.extension.observeNonNull
22
+ import io.github.mrtry.todolist.misc.ui.binding.Bindable
23
+ import io.github.mrtry.todolist.task.entity.Task
24
+ import kotlinx.coroutines.CoroutineScope
25
+ import kotlinx.coroutines.cancelChildren
26
+ import javax.inject.Inject
27
+
28
+
29
+ private const val KEY_TASK = " KEY_TASK"
30
+
31
+ class EditTaskDialogFragment : DialogFragment (), Injectable<EditTaskComponent>, Bindable<FragmentEditTaskBinding> {
32
+ companion object {
33
+ val TAG : String = EditTaskDialogFragment ::class .java.simpleName
34
+
35
+ fun newInstance (task : Task ): EditTaskDialogFragment {
36
+ val fragment = EditTaskDialogFragment ()
37
+ val args = Bundle ()
38
+ args.putParcelable(KEY_TASK , task)
39
+ fragment.arguments = args
40
+ return fragment
41
+ }
42
+ }
43
+
44
+ override val viewBinding: FragmentEditTaskBinding by lazy {
45
+ FragmentEditTaskBinding .inflate(layoutInflater)
46
+ }
47
+
48
+ override lateinit var component: EditTaskComponent
49
+
50
+ @Inject
51
+ lateinit var viewModel: EditTaskViewModel
52
+
53
+ @Inject
54
+ lateinit var navigator: EditTaskNavigator
55
+
56
+ @Inject
57
+ lateinit var coroutineScope: CoroutineScope
58
+
59
+ override fun onCreate (savedInstanceState : Bundle ? ) {
60
+ super .onCreate(savedInstanceState)
61
+ setStyle(STYLE_NORMAL , R .style.Widget_FullScreenDialog )
62
+ }
63
+
64
+ override fun onCreateView (inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ): View {
65
+ super .onCreateView(inflater, container, savedInstanceState)
66
+ return viewBinding.root
67
+ }
68
+
69
+ override fun onActivityCreated (savedInstanceState : Bundle ? ) {
70
+ super .onActivityCreated(savedInstanceState)
71
+ component = ComponentUtils .getComponent<ToDoComponent >(requireActivity())
72
+ .plusEditTaskComponent(FragmentModule (this ))
73
+ component.inject(this )
74
+
75
+ savedInstanceState?.let {
76
+ viewModel.onRestoreInstanceState(it)
77
+ }
78
+
79
+ with (viewBinding) {
80
+ viewModel = this @EditTaskDialogFragment.viewModel
81
+ lifecycleOwner = this @EditTaskDialogFragment
82
+ }
83
+
84
+ requireActivity().onBackPressedDispatcher.addCallback(this ) {
85
+ navigator.showSavingAlert()
86
+ }
87
+
88
+ // DialogFragmentのcancel()を無効にして、back pressをハンドリングする
89
+ // see: https://stackoverflow.com/a/7622065
90
+ isCancelable = false
91
+ dialog?.setOnKeyListener { _, keyCode, event ->
92
+ if (keyCode == KeyEvent .KEYCODE_BACK && event.action == = KeyEvent .ACTION_UP ) {
93
+ navigator.onBackPressed()
94
+ true
95
+ } else false
96
+ }
97
+
98
+ viewModel.title.observeNonNull(this @EditTaskDialogFragment) {
99
+ with (viewBinding.toolbar) {
100
+ menu.getItem(0 ).isEnabled = it.isNotEmpty()
101
+ invalidate()
102
+ }
103
+ }
104
+ }
105
+
106
+ override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
107
+ super .onViewCreated(view, savedInstanceState)
108
+ with (viewBinding.toolbar) {
109
+ setNavigationOnClickListener {
110
+ navigator.onBackPressed()
111
+ }
112
+
113
+ inflateMenu(R .menu.menu_fragment_edit_task)
114
+ setOnMenuItemClickListener {
115
+ this @EditTaskDialogFragment.viewModel.onSaveClick()
116
+ true
117
+ }
118
+ }
119
+ }
120
+
121
+ override fun onStart () {
122
+ super .onStart()
123
+ dialog?.window?.setLayout(
124
+ ViewGroup .LayoutParams .MATCH_PARENT ,
125
+ ViewGroup .LayoutParams .MATCH_PARENT
126
+ )
127
+ }
128
+
129
+ override fun onSaveInstanceState (outState : Bundle ) {
130
+ super .onSaveInstanceState(outState)
131
+ viewModel.onSaveInstanceState(outState)
132
+ }
133
+
134
+ override fun onStop () {
135
+ super .onStop()
136
+ coroutineScope.coroutineContext.cancelChildren()
137
+ }
138
+ }
139
+
140
+ @FragmentScope
141
+ class EditTaskDialogFragmentValueHolder
142
+ @Inject constructor (fragment: Fragment ) {
143
+ val task: Task = fragment.requireArguments().getParcelable(KEY_TASK )!!
144
+ }
0 commit comments