diff --git a/app/build.gradle b/app/build.gradle index 6ceb76a..8a6f831 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,8 +43,10 @@ compile "android.arch.lifecycle:runtime:1.1.0" compile "android.arch.lifecycle:extensions:1.1.0" annotationProcessor "android.arch.lifecycle:compiler:1.1.0" + implementation "android.arch.persistence.room:runtime:1.0.0" - annotationProcessor "android.arch.persistence.room:compiler:1.0.0" + implementation "android.arch.persistence.room:rxjava2:1.0.0" + kapt "android.arch.persistence.room:compiler:1.0.0" // Dagger2 implementation "com.google.dagger:dagger:$dagger_version" @@ -57,4 +59,9 @@ // Android Design Support Library compile 'com.android.support:design:26.1.0' + + // RxJava + implementation "io.reactivex.rxjava2:rxjava:2.1.7" + implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' + implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' } diff --git a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskActivity.kt b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskActivity.kt index 89797b1..2e87678 100644 --- a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskActivity.kt +++ b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskActivity.kt @@ -1,5 +1,7 @@ package keijumt.todoapp.addtask +import android.arch.lifecycle.Observer +import android.arch.lifecycle.ViewModelProviders import android.os.Bundle import android.support.v4.app.Fragment import dagger.android.AndroidInjector @@ -14,9 +16,19 @@ */ class AddEditTaskActivity : BaseActivity(), HasSupportFragmentInjector, Injectable { + lateinit var addEditTaskViewModel: AddEditTaskViewModel + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_add_edit_task) + addEditTaskViewModel = ViewModelProviders.of(this, viewModelFactory).get(AddEditTaskViewModel::class.java) + subscribe() + } + + fun subscribe() { + addEditTaskViewModel.taskAddEvent.observe(this, Observer { + finish() + }) } override fun supportFragmentInjector(): AndroidInjector { diff --git a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskFragment.kt b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskFragment.kt index bc51f0b..d3545e9 100644 --- a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskFragment.kt +++ b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskFragment.kt @@ -9,19 +9,25 @@ import android.view.ViewGroup import keijumt.todoapp.R import keijumt.todoapp.databinding.FragmentAddEditTaskBinding +import keijumt.todoapp.di.Injectable +import keijumt.todoapp.di.ViewModelFactory +import javax.inject.Inject /** * タスク追加のFragment * Created by matsumoto_k on 2018/03/06. */ -class AddEditTaskFragment : Fragment() { +class AddEditTaskFragment : Fragment(), Injectable { + + @Inject + lateinit var viewModelFactory: ViewModelFactory lateinit var binding: FragmentAddEditTaskBinding lateinit var addEditTaskViewModel: AddEditTaskViewModel override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = DataBindingUtil.inflate(inflater, R.layout.fragment_add_edit_task, null, false) - addEditTaskViewModel = ViewModelProviders.of(activity).get(AddEditTaskViewModel::class.java) + addEditTaskViewModel = ViewModelProviders.of(activity, viewModelFactory).get(AddEditTaskViewModel::class.java) binding.addEditTaskViewModel = addEditTaskViewModel lifecycle.addObserver(addEditTaskViewModel) return binding.root diff --git a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskViewModel.kt b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskViewModel.kt index 41103ac..72dcc9a 100644 --- a/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskViewModel.kt +++ b/app/src/main/java/keijumt/todoapp/addtask/AddEditTaskViewModel.kt @@ -2,14 +2,27 @@ import android.databinding.ObservableField import keijumt.todoapp.BaseViewModel +import keijumt.todoapp.data.db.entity.Task +import keijumt.todoapp.data.repository.TaskRepository +import keijumt.todoapp.databinding.SingleLiveEvent +import java.util.* import javax.inject.Inject /** * タスク追加のViewModel * Created by matsumoto_k on 2018/03/06. */ -class AddEditTaskViewModel @Inject constructor() : BaseViewModel() { +class AddEditTaskViewModel @Inject constructor( + val repository: TaskRepository +) : BaseViewModel() { - val taskTitle = ObservableField() - val taskDetails = ObservableField() + val taskTitle = ObservableField("") + val taskDetails = ObservableField("") + val taskAddEvent = SingleLiveEvent() + + fun onClickSave() { + val task = Task(taskTitle.get(), taskDetails.get(), Calendar.getInstance().timeInMillis, Calendar.getInstance().timeInMillis) + repository.save(task) + taskAddEvent.call() + } } \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/AppDatabase.kt b/app/src/main/java/keijumt/todoapp/data/db/AppDatabase.kt new file mode 100644 index 0000000..4bf465f --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/AppDatabase.kt @@ -0,0 +1,16 @@ +package keijumt.todoapp.data.db + +import android.arch.persistence.room.Database +import android.arch.persistence.room.RoomDatabase +import keijumt.todoapp.data.db.dao.TaskDao +import keijumt.todoapp.data.db.entity.Task + +@Database( + entities = arrayOf( + Task::class + ), + version = 1 +) +abstract class AppDatabase : RoomDatabase() { + abstract fun taskDao(): TaskDao +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/DateConverter.kt b/app/src/main/java/keijumt/todoapp/data/db/DateConverter.kt new file mode 100644 index 0000000..0fb97de --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/DateConverter.kt @@ -0,0 +1,20 @@ +package keijumt.todoapp.data.db + +import android.arch.persistence.room.TypeConverter +import java.util.* + + +/** + * Created by matsumoto_k on 2018/03/09. + */ +class DateConverter { + @TypeConverter + fun toDate(timestamp: Long?): Date? { + return if (timestamp == null) null else Date(timestamp) + } + + @TypeConverter + fun toTimestamp(date: Date?): Long? { + return date?.time?.toLong() + } +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/TaskDatabase.kt b/app/src/main/java/keijumt/todoapp/data/db/TaskDatabase.kt new file mode 100644 index 0000000..f1887a2 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/TaskDatabase.kt @@ -0,0 +1,13 @@ +package keijumt.todoapp.data.db + +import io.reactivex.Flowable +import keijumt.todoapp.data.db.entity.Task + +/** + * Created by matsumoto_k on 2018/03/09. + */ +interface TaskDatabase { + fun getAll(): Flowable> + fun save(task: Task) + fun update(task: Task) +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/TaskRoomDatabase.kt b/app/src/main/java/keijumt/todoapp/data/db/TaskRoomDatabase.kt new file mode 100644 index 0000000..79df173 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/TaskRoomDatabase.kt @@ -0,0 +1,31 @@ +package keijumt.todoapp.data.db + +import android.arch.persistence.room.RoomDatabase +import io.reactivex.Flowable +import keijumt.todoapp.data.db.dao.TaskDao +import keijumt.todoapp.data.db.entity.Task +import javax.inject.Inject + +/** + * Created by matsumoto_k on 2018/03/09. + */ +class TaskRoomDatabase @Inject constructor( + val database: RoomDatabase, + val taskDao: TaskDao +) : TaskDatabase { + override fun getAll(): Flowable> { + return taskDao.getAll() + } + + override fun save(task: Task) { + database.runInTransaction { + taskDao.insert(task) + } + } + + override fun update(task: Task) { + database.runInTransaction { + taskDao.update(task) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/dao/TaskDao.kt b/app/src/main/java/keijumt/todoapp/data/db/dao/TaskDao.kt new file mode 100644 index 0000000..420a3ff --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/dao/TaskDao.kt @@ -0,0 +1,25 @@ +package keijumt.todoapp.data.db.dao + +import android.arch.persistence.room.* +import io.reactivex.Flowable +import keijumt.todoapp.data.db.entity.Task + +/** + * TaskのDao + * Created by matsumoto_k on 2018/03/09. + */ +@Dao +abstract class TaskDao { + + @Query("SELECT * FROM task") + abstract fun getAll(): Flowable> + + @Insert + abstract fun insert(task: Task) + + @Delete + abstract fun delete(task: Task) + + @Update(onConflict = OnConflictStrategy.REPLACE) + abstract fun update(task: Task) +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/db/entity/Task.kt b/app/src/main/java/keijumt/todoapp/data/db/entity/Task.kt new file mode 100644 index 0000000..009ccb6 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/db/entity/Task.kt @@ -0,0 +1,25 @@ +package keijumt.todoapp.data.db.entity + +import android.arch.persistence.room.ColumnInfo +import android.arch.persistence.room.Entity +import android.arch.persistence.room.PrimaryKey +import java.util.* + +/** + * タスクのEntity + * Created by matsumoto_k on 2018/03/09. + */ +@Entity(tableName = "task") +data class Task( + @ColumnInfo(name = "task_title") + var title: String = "", + @ColumnInfo(name = "task_details") + var details: String = "", + @ColumnInfo(name = "task_modified") + var modified: Long = Calendar.getInstance().time.time, + @ColumnInfo(name = "task_created") + var created: Long = Calendar.getInstance().time.time +) { + @PrimaryKey + var id: String = UUID.randomUUID().toString() +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/repository/TaskDataRepository.kt b/app/src/main/java/keijumt/todoapp/data/repository/TaskDataRepository.kt new file mode 100644 index 0000000..b060260 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/repository/TaskDataRepository.kt @@ -0,0 +1,23 @@ +package keijumt.todoapp.data.repository + +import io.reactivex.Flowable +import keijumt.todoapp.data.db.TaskDatabase +import keijumt.todoapp.data.db.entity.Task +import javax.inject.Inject +import kotlin.concurrent.thread + +/** + * TaskのRepository + * Created by matsumoto_k on 2018/03/09. + */ +class TaskDataRepository @Inject constructor( + val database: TaskDatabase +) : TaskRepository { + override val tasks: Flowable> = database.getAll() + + override fun save(task: Task) { + thread { + database.save(task) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/data/repository/TaskRepository.kt b/app/src/main/java/keijumt/todoapp/data/repository/TaskRepository.kt new file mode 100644 index 0000000..84ee14f --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/data/repository/TaskRepository.kt @@ -0,0 +1,12 @@ +package keijumt.todoapp.data.repository + +import io.reactivex.Flowable +import keijumt.todoapp.data.db.entity.Task + +/** + * Created by matsumoto_k on 2018/03/09. + */ +interface TaskRepository { + val tasks: Flowable> + fun save(task: Task) +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt b/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt index 7bf5c2d..ccdb04f 100644 --- a/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt +++ b/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt @@ -14,6 +14,6 @@ @ContributesAndroidInjector internal abstract fun contributeMainActivity(): MainActivity - @ContributesAndroidInjector + @ContributesAndroidInjector(modules = arrayOf(FragmentBuildersModule::class)) internal abstract fun contributeAddEditActivity(): AddEditTaskActivity } \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/AppComponent.kt b/app/src/main/java/keijumt/todoapp/di/AppComponent.kt index 454d532..1123b1e 100644 --- a/app/src/main/java/keijumt/todoapp/di/AppComponent.kt +++ b/app/src/main/java/keijumt/todoapp/di/AppComponent.kt @@ -12,7 +12,9 @@ @Component(modules = arrayOf( AndroidSupportInjectionModule::class, AppModule::class, + DatabaseModule::class, ActivityModule::class, + ViewModelModule::class, ServiceModule::class) ) interface AppComponent : AndroidInjector { diff --git a/app/src/main/java/keijumt/todoapp/di/AppModule.kt b/app/src/main/java/keijumt/todoapp/di/AppModule.kt index 2bf496c..3b8a569 100644 --- a/app/src/main/java/keijumt/todoapp/di/AppModule.kt +++ b/app/src/main/java/keijumt/todoapp/di/AppModule.kt @@ -1,7 +1,17 @@ package keijumt.todoapp.di import dagger.Module +import dagger.Provides +import keijumt.todoapp.data.db.TaskDatabase +import keijumt.todoapp.data.repository.TaskDataRepository +import keijumt.todoapp.data.repository.TaskRepository +import javax.inject.Singleton -@Module(includes = arrayOf(ViewModelModule::class)) +@Module class AppModule { + + @Singleton + @Provides + fun provideTaskRepository(database: TaskDatabase): TaskRepository = TaskDataRepository(database) + } \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/DatabaseModule.kt b/app/src/main/java/keijumt/todoapp/di/DatabaseModule.kt new file mode 100644 index 0000000..b56bc84 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/DatabaseModule.kt @@ -0,0 +1,33 @@ +package keijumt.todoapp.di + +import android.app.Application +import android.arch.persistence.room.Room +import dagger.Module +import dagger.Provides +import keijumt.todoapp.data.db.AppDatabase +import keijumt.todoapp.data.db.TaskDatabase +import keijumt.todoapp.data.db.TaskRoomDatabase +import keijumt.todoapp.data.db.dao.TaskDao +import javax.inject.Singleton + +/** + * + * Created by matsumoto_k on 2018/03/09. + */ +@Module +class DatabaseModule { + + @Singleton + @Provides + fun provideTaskDatabase(db: AppDatabase, dao: TaskDao): TaskDatabase = TaskRoomDatabase(db, dao) + + @Singleton + @Provides + fun provideDb(app: Application): AppDatabase = Room.databaseBuilder(app, AppDatabase::class.java, "toDoApp.db") + .fallbackToDestructiveMigration() + .build() + + @Singleton + @Provides + fun provideTaskDao(db: AppDatabase): TaskDao = db.taskDao() +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_add_edit_task.xml b/app/src/main/res/layout/fragment_add_edit_task.xml index 18a1c1a..0f36175 100644 --- a/app/src/main/res/layout/fragment_add_edit_task.xml +++ b/app/src/main/res/layout/fragment_add_edit_task.xml @@ -47,6 +47,7 @@ android:layout_marginBottom="@dimen/margin_medium" android:layout_marginEnd="@dimen/margin_medium" android:clickable="true" + android:onClick="@{() -> addEditTaskViewModel.onClickSave()}" android:src="@drawable/ic_check" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" />