diff --git a/Android/app/src/androidTest/java/com/example/todo_list/ExampleInstrumentedTest.kt b/Android/app/src/androidTest/java/com/example/todolist/ExampleInstrumentedTest.kt similarity index 90% rename from Android/app/src/androidTest/java/com/example/todo_list/ExampleInstrumentedTest.kt rename to Android/app/src/androidTest/java/com/example/todolist/ExampleInstrumentedTest.kt index 6022a5dee..5ff64659a 100644 --- a/Android/app/src/androidTest/java/com/example/todo_list/ExampleInstrumentedTest.kt +++ b/Android/app/src/androidTest/java/com/example/todolist/ExampleInstrumentedTest.kt @@ -1,13 +1,11 @@ -package com.example.todo_list +package com.example.todolist -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml index c16b39e34..cce329e73 100644 --- a/Android/app/src/main/AndroidManifest.xml +++ b/Android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.example.todolist"> @@ -12,7 +12,7 @@ android:supportsRtl="true" android:theme="@style/Theme.Todolist"> diff --git a/Android/app/src/main/java/com/example/todo_list/Repository.kt b/Android/app/src/main/java/com/example/todo_list/Repository.kt deleted file mode 100644 index 67ff71b32..000000000 --- a/Android/app/src/main/java/com/example/todo_list/Repository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.todo_list - -import com.example.todo_list.history.data.HistoryCard -import retrofit2.Response - -interface Repository { - suspend fun getHistory(): Response> -} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/history/HistoryReceive.kt b/Android/app/src/main/java/com/example/todo_list/history/HistoryReceive.kt deleted file mode 100644 index d9c4198cf..000000000 --- a/Android/app/src/main/java/com/example/todo_list/history/HistoryReceive.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.todo_list.history - -import com.example.todo_list.history.data.HistoryCard -import retrofit2.Response -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import retrofit2.http.GET -import retrofit2.http.Path - -class HistoryReceive { - companion object RetrofitApiObject { - private val retrofit = - Retrofit.Builder() - .baseUrl("https://f278a12c-c825-466b-aa01-65337bbdf28a.mock.pstmn.io/") - .addConverterFactory(GsonConverterFactory.create()) - .build() - val service: HistoryApi = retrofit.create(HistoryApi::class.java) - } -} - -interface HistoryApi { - @GET("api/{todos}") - suspend fun getHistory(@Path("todos") variable: String): Response> -} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/history/HistoryViewModel.kt b/Android/app/src/main/java/com/example/todo_list/history/HistoryViewModel.kt deleted file mode 100644 index b72e0dd5b..000000000 --- a/Android/app/src/main/java/com/example/todo_list/history/HistoryViewModel.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.todo_list.history - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.example.todo_list.Repository -import com.example.todo_list.history.data.HistoryCard -import kotlinx.coroutines.launch - -class HistoryViewModel(private val repository: Repository): ViewModel() { - private val _historyList = MutableLiveData>() - val historyList: LiveData> get() = _historyList - - private val _checkLoading = MutableLiveData() - val checkLoading: LiveData get() = _checkLoading - - fun getHistory() { - _checkLoading.value = true - viewModelScope.launch { - val response = repository.getHistory() - if (response.isSuccessful) { - _historyList.value = response.body() - _checkLoading.value = false - } - } - } -} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/history/data/HistoryCard.kt b/Android/app/src/main/java/com/example/todo_list/history/data/HistoryCard.kt deleted file mode 100644 index a4d3b2416..000000000 --- a/Android/app/src/main/java/com/example/todo_list/history/data/HistoryCard.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.todo_list.history.data - -import com.google.gson.annotations.SerializedName - -data class HistoryCard( - val id: Int, - val todo: Todo, - - val action: String, - @SerializedName("from status") - val from_status: String, - @SerializedName("to status") - val to_status: String, - val createdDateTime: String -) - -data class Todo( - val id: Int, - val title: String, - val contents: String, - val user: String, - val status: String, - val createdDateTime: String, - val updatedDateTime: String -) diff --git a/Android/app/src/main/java/com/example/todo_list/history/data/HistoryRepository.kt b/Android/app/src/main/java/com/example/todo_list/history/data/HistoryRepository.kt deleted file mode 100644 index 9f6204557..000000000 --- a/Android/app/src/main/java/com/example/todo_list/history/data/HistoryRepository.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.todo_list.history.data - -import com.example.todo_list.Repository -import com.example.todo_list.history.HistoryReceive -import retrofit2.Response - -class HistoryRepository : Repository { - private val retrofit = HistoryReceive.service - - override suspend fun getHistory(): Response> { - return retrofit.getHistory("histories") - } -} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/MainActivity.kt b/Android/app/src/main/java/com/example/todolist/MainActivity.kt similarity index 61% rename from Android/app/src/main/java/com/example/todo_list/MainActivity.kt rename to Android/app/src/main/java/com/example/todolist/MainActivity.kt index 3293b293c..5c1fbbef1 100644 --- a/Android/app/src/main/java/com/example/todo_list/MainActivity.kt +++ b/Android/app/src/main/java/com/example/todolist/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.todo_list +package com.example.todolist import android.os.Bundle import android.view.MenuItem @@ -7,35 +7,35 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GravityCompat import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider -import androidx.recyclerview.widget.LinearLayoutManager -import com.example.todo_list.databinding.ActivityMainBinding -import com.example.todo_list.history.HistoryAdapter -import com.example.todo_list.history.HistoryViewModel -import com.example.todo_list.history.data.HistoryRepository +import com.example.todolist.data.TasksRepository +import com.example.todolist.databinding.ActivityMainBinding +import com.example.todolist.history.HistoryAdapter +import com.example.todolist.tasks.data.Task import com.google.android.material.navigation.NavigationView class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { private lateinit var binding: ActivityMainBinding - private lateinit var historyViewModel: HistoryViewModel + private lateinit var tasksViewModel: TasksViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_main) - historyViewModel = ViewModelProvider(this, ViewModelFactory(HistoryRepository())).get(HistoryViewModel::class.java) + tasksViewModel = ViewModelProvider(this, ViewModelFactory(TasksRepository())).get( + TasksViewModel::class.java) - val adapter = HistoryAdapter() - binding.recyclerviewHistory.adapter = adapter - binding.recyclerviewHistory.layoutManager = LinearLayoutManager(this) + val historyAdapter = HistoryAdapter() + binding.recyclerviewHistory.adapter = historyAdapter binding.btnMenu.setOnClickListener { binding.mainLayout.openDrawer(GravityCompat.END) - historyViewModel.getHistory() + tasksViewModel.getHistories() } + binding.btnClose.setOnClickListener { binding.mainLayout.closeDrawer(GravityCompat.END) } binding.naviView.setNavigationItemSelectedListener(this) - historyViewModel.historyList.observe(this) { adapter.submitList(it) } - historyViewModel.checkLoading.observe(this) { + tasksViewModel.historyList.observe(this) { historyAdapter.submitList(it) } + tasksViewModel.checkLoading.observe(this) { if (it) { binding.spinner.visibility = View.VISIBLE binding.recyclerviewHistory.visibility = View.GONE @@ -44,6 +44,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte binding.recyclerviewHistory.visibility = View.VISIBLE } } + + binding.todoTodoView.addTasks(tasksViewModel.getSomeTasks()) } override fun onNavigationItemSelected(item: MenuItem): Boolean { diff --git a/Android/app/src/main/java/com/example/todolist/TasksViewModel.kt b/Android/app/src/main/java/com/example/todolist/TasksViewModel.kt new file mode 100644 index 000000000..ce4ae0f4c --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/TasksViewModel.kt @@ -0,0 +1,53 @@ +package com.example.todolist + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.todolist.data.Repository +import com.example.todolist.history.data.HistoryCard +import com.example.todolist.tasks.data.Task +import kotlinx.coroutines.launch + +class TasksViewModel(private val repository: Repository): ViewModel() { + private val _historyList = MutableLiveData>() + val historyList: LiveData> get() = _historyList + + private val _checkLoading = MutableLiveData() + val checkLoading: LiveData get() = _checkLoading + + fun getHistories() { + _checkLoading.value = true + viewModelScope.launch { + val response = repository.getHistories() + if (response.isSuccessful) { + _historyList.value = response.body() + _checkLoading.value = false + } + } + } + + fun getSomeTasks(): List { + val task1 = Task( + 1, + "테스트하기1", + "콘텐츠테스트1", + "jung", + "doing", + "2022-04-06T15:30:00.000+09:00", + "2022-04-06T15:30:00.000+09:00" + ) + + val task2 = Task( + 2, + "테스트하기2", + "콘텐츠테스트2", + "park", + "todo", + "2022-04-06T15:30:00.000+09:00", + "2022-04-06T15:30:00.000+09:00" + ) + + return listOf(task1, task2) + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/ViewModelFactory.kt b/Android/app/src/main/java/com/example/todolist/ViewModelFactory.kt similarity index 62% rename from Android/app/src/main/java/com/example/todo_list/ViewModelFactory.kt rename to Android/app/src/main/java/com/example/todolist/ViewModelFactory.kt index 3aab2deae..3447b87d5 100644 --- a/Android/app/src/main/java/com/example/todo_list/ViewModelFactory.kt +++ b/Android/app/src/main/java/com/example/todolist/ViewModelFactory.kt @@ -1,13 +1,13 @@ -package com.example.todo_list +package com.example.todolist import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.example.todo_list.history.HistoryViewModel +import com.example.todolist.data.Repository class ViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return if (modelClass.isAssignableFrom(HistoryViewModel::class.java)) { - HistoryViewModel(repository) as T + return if (modelClass.isAssignableFrom(TasksViewModel::class.java)) { + TasksViewModel(repository) as T } else { throw Exception("클래스가 존재하지 않습니다.") } diff --git a/Android/app/src/main/java/com/example/todolist/data/Repository.kt b/Android/app/src/main/java/com/example/todolist/data/Repository.kt new file mode 100644 index 000000000..7b5be0eaa --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/data/Repository.kt @@ -0,0 +1,19 @@ +package com.example.todolist.data + +import com.example.todolist.history.data.HistoryCard +import com.example.todolist.tasks.data.Task +import retrofit2.Response + +interface Repository { + suspend fun getHistories(): Response> + + suspend fun getAllTasks(): Response> + + suspend fun getTask(id: Int): Response + + suspend fun createTask(title: String, contents: String, user: String, status: String): Response + + suspend fun deleteTask(id: Int) + + suspend fun updateTask(id: Int, param: HashMap): Response +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/data/TasksRepository.kt b/Android/app/src/main/java/com/example/todolist/data/TasksRepository.kt new file mode 100644 index 000000000..d21132c2f --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/data/TasksRepository.kt @@ -0,0 +1,47 @@ +package com.example.todolist.data + +import com.example.todolist.history.data.HistoryCard +import com.example.todolist.network.NetworkModule +import com.example.todolist.tasks.data.Task +import retrofit2.Response + +class TasksRepository : Repository { + private val network = NetworkModule.service + + override suspend fun getHistories(): Response> { + return network.getHistories("histories") + } + + override suspend fun getAllTasks(): Response> { + return network.getAllTasks() + } + + override suspend fun getTask(id: Int): Response { + return network.getTask(id) + } + + override suspend fun createTask( + title: String, + contents: String, + user: String, + status: String + ): Response { + return network.createTask( + title, + contents, + user, + status + ) + } + + override suspend fun deleteTask(id: Int) { + network.deleteTask(id) + } + + override suspend fun updateTask(id: Int, param: HashMap): Response { + return network.updateTask( + id, + param + ) + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todo_list/history/BindingAdapters.kt b/Android/app/src/main/java/com/example/todolist/history/BindingAdapters.kt similarity index 84% rename from Android/app/src/main/java/com/example/todo_list/history/BindingAdapters.kt rename to Android/app/src/main/java/com/example/todolist/history/BindingAdapters.kt index 5fb77a155..924784fb5 100644 --- a/Android/app/src/main/java/com/example/todo_list/history/BindingAdapters.kt +++ b/Android/app/src/main/java/com/example/todolist/history/BindingAdapters.kt @@ -1,12 +1,12 @@ -package com.example.todo_list.history +package com.example.todolist.history import android.text.format.DateUtils import android.widget.TextView import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY import androidx.databinding.BindingAdapter -import com.example.todo_list.R -import com.example.todo_list.history.data.HistoryCard +import com.example.todolist.R +import com.example.todolist.history.data.HistoryCard import java.text.SimpleDateFormat import java.util.* @@ -39,9 +39,9 @@ fun setBody(view: TextView, body: HistoryCard) { HtmlCompat.fromHtml( view.context.getString( R.string.history_move_string, - body.todo.contents, - convertStatus(body.from_status), - convertStatus(body.to_status), + body.todoTitle, + convertStatus(body.fromStatus), + convertStatus(body.toStatus), convertAction(body.action) ), FROM_HTML_MODE_LEGACY @@ -50,8 +50,8 @@ fun setBody(view: TextView, body: HistoryCard) { HtmlCompat.fromHtml( view.context.getString( R.string.history_default_string, - convertStatus(body.todo.status), - body.todo.contents, + convertStatus(body.toStatus), + body.todoTitle, convertAction(body.action) ), FROM_HTML_MODE_LEGACY diff --git a/Android/app/src/main/java/com/example/todo_list/history/HistoryAdapter.kt b/Android/app/src/main/java/com/example/todolist/history/HistoryAdapter.kt similarity index 87% rename from Android/app/src/main/java/com/example/todo_list/history/HistoryAdapter.kt rename to Android/app/src/main/java/com/example/todolist/history/HistoryAdapter.kt index 62e2200d7..15a1702e8 100644 --- a/Android/app/src/main/java/com/example/todo_list/history/HistoryAdapter.kt +++ b/Android/app/src/main/java/com/example/todolist/history/HistoryAdapter.kt @@ -1,4 +1,4 @@ -package com.example.todo_list.history +package com.example.todolist.history import android.view.LayoutInflater import android.view.ViewGroup @@ -6,9 +6,9 @@ import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import com.example.todo_list.R -import com.example.todo_list.databinding.HistoryItemBinding -import com.example.todo_list.history.data.HistoryCard +import com.example.todolist.R +import com.example.todolist.databinding.HistoryItemBinding +import com.example.todolist.history.data.HistoryCard class HistoryAdapter : ListAdapter(diffUtil) { inner class HistoryViewHolder(private val binding: HistoryItemBinding) : RecyclerView.ViewHolder(binding.root) { diff --git a/Android/app/src/main/java/com/example/todolist/history/data/HistoryCard.kt b/Android/app/src/main/java/com/example/todolist/history/data/HistoryCard.kt new file mode 100644 index 000000000..be9f108b9 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/history/data/HistoryCard.kt @@ -0,0 +1,12 @@ +package com.example.todolist.history.data + +data class HistoryCard( + val id: Int, + val todoId: Int, + val todoTitle: String, + val user: String, + val action: String, + val fromStatus: String, + val toStatus: String, + val createdAt: String +) diff --git a/Android/app/src/main/java/com/example/todolist/network/NetworkModule.kt b/Android/app/src/main/java/com/example/todolist/network/NetworkModule.kt new file mode 100644 index 000000000..22b56417b --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/network/NetworkModule.kt @@ -0,0 +1,17 @@ +package com.example.todolist.network + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class NetworkModule { + companion object RetrofitApiObject { + private const val BASE_URL = "https://f278a12c-c825-466b-aa01-65337bbdf28a.mock.pstmn.io/" + + private val retrofit = + Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + val service: TodoService = retrofit.create(TodoService::class.java) + } +} diff --git a/Android/app/src/main/java/com/example/todolist/network/TodoService.kt b/Android/app/src/main/java/com/example/todolist/network/TodoService.kt new file mode 100644 index 000000000..464416e50 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/network/TodoService.kt @@ -0,0 +1,43 @@ +package com.example.todolist.network + +import com.example.todolist.history.data.HistoryCard +import com.example.todolist.tasks.data.Task +import retrofit2.Response +import retrofit2.http.* + +interface TodoService { + + @GET("api/{histories}") + suspend fun getHistories( + @Path("histories") variable: String + ): Response> + + @GET("api/todos") + suspend fun getAllTasks(): Response> + + @GET("api/todos/{id}") + suspend fun getTask( + @Path("id") id: Int + ): Response + + @FormUrlEncoded + @POST("api/todos") + suspend fun createTask( + @Field("title") title: String, + @Field("contents") contents: String, + @Field("user") user: String, + @Field("status") status: String, + ): Response + + @DELETE("api/todos/{id}") + suspend fun deleteTask( + @Path("id") id: Int + ): Response + + @FormUrlEncoded + @PATCH("api/todos/{id}") + suspend fun updateTask( + @Path("id") id: Int, + @FieldMap param: HashMap + ): Response +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperCallback.kt b/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperCallback.kt new file mode 100644 index 000000000..154ce9094 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperCallback.kt @@ -0,0 +1,107 @@ +package com.example.todolist.tasks + +import android.graphics.Canvas +import android.util.Log +import android.view.View +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import com.example.todolist.R +import kotlin.math.min + +class ItemTouchHelperCallback(val listener: ItemTouchHelperListener) : ItemTouchHelper.Callback() { + + private var clamp = 0f + private var currentDx = 0f + + override fun getMovementFlags( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ): Int { + Log.d("TAGcode", "${ItemTouchHelper.LEFT}") + return makeMovementFlags(0, ItemTouchHelper.LEFT) + } + + override fun onMove( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + target: RecyclerView.ViewHolder + ): Boolean { + return listener.onItemMove(viewHolder.adapterPosition, target.adapterPosition) + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + Log.d("TAGonSwiped1", "$direction") + Log.d("TAGonSwiped2", "${viewHolder.adapterPosition}") //<< 몇번째 목록을 조작했는지 + // direction = 방향 >> 왼쪽으로 스와이프했을때 작동 + listener.onItemSwipe(viewHolder.adapterPosition) + + } + + // 터치,스와이프등 뷰에 변화가 생길겨여우 + override fun onChildDraw( + c: Canvas, + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + actionState: Int, + isCurrentlyActive: Boolean + ) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + val view = getView(viewHolder) + val isClamped = getTag(viewHolder) + val newX = clampViewPositionHorizontal( + dX, + isClamped, + isCurrentlyActive + ) // newX 만큼 이동(고정 시 이동 위치/고정 해제 시 이동 위치 결정) + + // 고정시킬 시 애니메이션 추가 + if (newX == -clamp) { + getView(viewHolder).animate().translationX(-clamp).setDuration(100L).start() + return + } + + currentDx = newX + getDefaultUIUtil().onDraw( + c, + recyclerView, + view, + newX, + dY, + actionState, + isCurrentlyActive + ) + } + } + + fun setClamp(clamp: Float) { this.clamp = clamp } + private fun getView(viewHolder: RecyclerView.ViewHolder) : View = viewHolder.itemView.findViewById(R.id.todo_item) + private fun getTag(viewHolder: RecyclerView.ViewHolder) : Boolean = viewHolder.itemView.tag as? Boolean ?: false + + private fun clampViewPositionHorizontal( + dX: Float, + isClamped: Boolean, + isCurrentlyActive: Boolean + ) : Float { + // RIGHT 방향으로 swipe 막기 + val max = 0f + + // 고정할 수 있으면 + val newX = if (isClamped) { + // 현재 swipe 중이면 swipe되는 영역 제한 + if (isCurrentlyActive) + // 오른쪽 swipe일 때 + if (dX < 0) dX/3 - clamp + // 왼쪽 swipe일 때 + else dX - clamp + // swipe 중이 아니면 고정시키기 + else -clamp + } + // 고정할 수 없으면 newX는 스와이프한 만큼 + else dX / 2 + + // newX가 0보다 작은지 확인 + return min(newX, max) + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperListener.kt b/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperListener.kt new file mode 100644 index 000000000..954fa752b --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/ItemTouchHelperListener.kt @@ -0,0 +1,6 @@ +package com.example.todolist.tasks + +interface ItemTouchHelperListener { + fun onItemMove(from_position: Int, to_position: Int): Boolean + fun onItemSwipe(position: Int) +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/TaskAdapter.kt b/Android/app/src/main/java/com/example/todolist/tasks/TaskAdapter.kt new file mode 100644 index 000000000..5a199b709 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/TaskAdapter.kt @@ -0,0 +1,53 @@ +package com.example.todolist.tasks + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.todolist.R +import com.example.todolist.databinding.TodoItemBinding +import com.example.todolist.tasks.data.Task + +class TodoAdapter : ListAdapter(diffUtil), + ItemTouchHelperListener { + inner class TodoViewHolder(private val binding: TodoItemBinding) : RecyclerView.ViewHolder(binding.root) { + fun bind(task: Task) { + binding.task = task + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + DataBindingUtil.inflate( + LayoutInflater.from(parent.context), + R.layout.todo_item, + parent, + false + ).let { + TodoViewHolder(it) + } + + override fun onBindViewHolder(holder: TodoViewHolder, position: Int) { + val item = getItem(position) + holder.bind(item) + } + + override fun onItemMove(from_position: Int, to_position: Int): Boolean { + return true + } + + override fun onItemSwipe(position: Int) { + } +} + +private val diffUtil = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Task, newItem: Task): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: Task, newItem: Task): Boolean { + return oldItem == newItem + } + +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/TaskBindingAdapters.kt b/Android/app/src/main/java/com/example/todolist/tasks/TaskBindingAdapters.kt new file mode 100644 index 000000000..d76a0d32b --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/TaskBindingAdapters.kt @@ -0,0 +1,19 @@ +package com.example.todolist.tasks + +import android.widget.TextView +import androidx.databinding.BindingAdapter + +@BindingAdapter("setTitle") +fun setTitle(view: TextView, title: String) { + view.text = title +} + +@BindingAdapter("setContent") +fun setContent(view: TextView, content: String) { + view.text = content +} + +@BindingAdapter("setUser") +fun setUser(view: TextView, user: String) { + view.text = user +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/TasksView.kt b/Android/app/src/main/java/com/example/todolist/tasks/TasksView.kt new file mode 100644 index 000000000..859ce81a2 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/TasksView.kt @@ -0,0 +1,57 @@ +package com.example.todolist.tasks + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.ImageButton +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import com.example.todolist.R +import com.example.todolist.databinding.TasksViewBinding +import com.example.todolist.tasks.data.Task + +class TasksView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) { + + private lateinit var binding: TasksViewBinding + private val todosAdapter = TodoAdapter() + init { + initViews() + initAttributes(attrs) + } + + private fun initAttributes(attrs: AttributeSet?) { + context.theme.obtainStyledAttributes( + attrs, + R.styleable.TodoView, + 0, + 0).apply { + try { + binding.todoTitle.text = getString(R.styleable.TodoView_title) + binding.todoBadge.text = getString(R.styleable.TodoView_badge_count) + } finally { + recycle() + } + } + } + + private fun initViews() { + val layoutInflater = context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE + ) as LayoutInflater + + binding = TasksViewBinding.inflate(layoutInflater, this, false) + addView(binding.root) + + binding.recyclerviewTodo.adapter = todosAdapter + binding.recyclerviewTodo.setHasFixedSize(true) + val touchHelper = ItemTouchHelperCallback(todosAdapter) + val helper = ItemTouchHelper(touchHelper) + helper.attachToRecyclerView(binding.recyclerviewTodo) + } + + fun addTasks(tasks: List) { + todosAdapter.submitList(tasks) + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/todolist/tasks/data/Task.kt b/Android/app/src/main/java/com/example/todolist/tasks/data/Task.kt new file mode 100644 index 000000000..00a27bed0 --- /dev/null +++ b/Android/app/src/main/java/com/example/todolist/tasks/data/Task.kt @@ -0,0 +1,11 @@ +package com.example.todolist.tasks.data + +data class Task( + val id: Int, + val title: String, + val contents: String, + val user: String, + val status: String, + val createdDateTime: String, + val updatedDateTime: String +) diff --git a/Android/app/src/main/res/drawable/ic_baseline_add_24.xml b/Android/app/src/main/res/drawable/ic_baseline_add_24.xml new file mode 100644 index 000000000..000eb3e52 --- /dev/null +++ b/Android/app/src/main/res/drawable/ic_baseline_add_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/Android/app/src/main/res/drawable/todo_badge_bg.xml b/Android/app/src/main/res/drawable/todo_badge_bg.xml new file mode 100644 index 000000000..9fffb38d1 --- /dev/null +++ b/Android/app/src/main/res/drawable/todo_badge_bg.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout-sw720dp/activity_main.xml b/Android/app/src/main/res/layout-sw720dp/activity_main.xml index 095248244..5c3b2f8f4 100644 --- a/Android/app/src/main/res/layout-sw720dp/activity_main.xml +++ b/Android/app/src/main/res/layout-sw720dp/activity_main.xml @@ -1,5 +1,7 @@ + tools:openDrawer="start"> - + android:layout_height="match_parent"> + android:background="@color/background" + custom:layout_constraintEnd_toEndOf="parent" + custom:layout_constraintStart_toStartOf="parent" + custom:layout_constraintTop_toTopOf="parent"> - + + + + + + + + - \ No newline at end of file diff --git a/Android/app/src/main/res/layout-sw720dp/history_item.xml b/Android/app/src/main/res/layout-sw720dp/history_item.xml index 78e1150ad..3865c04fb 100644 --- a/Android/app/src/main/res/layout-sw720dp/history_item.xml +++ b/Android/app/src/main/res/layout-sw720dp/history_item.xml @@ -8,7 +8,7 @@ + type="com.example.todolist.history.data.HistoryCard" /> @@ -37,7 +37,7 @@ android:textAppearance="@style/history_user_name" app:layout_constraintStart_toEndOf="@id/user_img" app:layout_constraintTop_toTopOf="parent" - bind:setUsername="@{historyCard.todo.user}" + bind:setUsername="@{historyCard.user}" tools:text="\@sam" /> diff --git a/Android/app/src/main/res/layout-sw720dp/tasks_view.xml b/Android/app/src/main/res/layout-sw720dp/tasks_view.xml new file mode 100644 index 000000000..0f8e36cba --- /dev/null +++ b/Android/app/src/main/res/layout-sw720dp/tasks_view.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout-sw720dp/todo_item.xml b/Android/app/src/main/res/layout-sw720dp/todo_item.xml new file mode 100644 index 000000000..f2711b89e --- /dev/null +++ b/Android/app/src/main/res/layout-sw720dp/todo_item.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/activity_main.xml b/Android/app/src/main/res/layout/activity_main.xml index 6592fca58..5c3b2f8f4 100644 --- a/Android/app/src/main/res/layout/activity_main.xml +++ b/Android/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,7 @@ + tools:openDrawer="start"> - + android:layout_height="match_parent"> + android:background="@color/background" + custom:layout_constraintEnd_toEndOf="parent" + custom:layout_constraintStart_toStartOf="parent" + custom:layout_constraintTop_toTopOf="parent"> @@ -37,7 +42,7 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="end" - android:layout_marginEnd="12dp" + android:layout_marginEnd="35dp" android:background="@color/transparent" android:contentDescription="@string/menu" android:src="@drawable/ic_baseline_menu_24" /> @@ -45,11 +50,51 @@ - + + + + + + + + @@ -59,19 +104,20 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="end" - android:layout_marginTop="12dp" - android:layout_marginEnd="12dp" + android:layout_marginTop="24dp" + android:layout_marginEnd="48dp" android:background="@color/transparent" android:contentDescription="@string/close" android:src="@drawable/ic_close" /> - \ No newline at end of file diff --git a/Android/app/src/main/res/layout/tasks_view.xml b/Android/app/src/main/res/layout/tasks_view.xml new file mode 100644 index 000000000..0f8e36cba --- /dev/null +++ b/Android/app/src/main/res/layout/tasks_view.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/todo_item.xml b/Android/app/src/main/res/layout/todo_item.xml new file mode 100644 index 000000000..11225e147 --- /dev/null +++ b/Android/app/src/main/res/layout/todo_item.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + +