Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI/#45] MyTodo / 생성화면 UI 구현 #52

Merged
merged 18 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

<activity
android:name="com.going.presentation.todo.TodoActivity"
android:exported="false"
android:exported="true"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세연이가 화가 많이 났습니다...
false로 바꿔서 올려주세용...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅠㅠ혼났어요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr 올릴 때 true 말고 false 부탁드립니다~!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋ.ㅋ

android:screenOrientation="portrait" />

<activity
Expand Down Expand Up @@ -96,7 +96,12 @@
<activity
android:name="com.going.presentation.starttrip.StartTripSplashActivity"
android:exported="false"
android:screenOrientation="portrait"/>
android:screenOrientation="portrait" />

<activity
android:name="com.going.presentation.todo.mytodo.create.MyTodoCreateActivity"
android:exported="false"
android:screenOrientation="portrait" />

<activity
android:name="com.going.presentation.starttrip.finishtrip.FinishTripActivity"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.going.presentation.todo.mytodo

import android.content.Intent
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
Expand All @@ -11,8 +12,10 @@ import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.going.presentation.R
import com.going.presentation.databinding.FragmentMyTodoBinding
import com.going.presentation.todo.mytodo.create.MyTodoCreateActivity
import com.going.presentation.todo.mytodo.todolist.MyTodoViewPagerAdapter
import com.going.ui.base.BaseFragment
import com.going.ui.extension.setOnSingleClickListener
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
Expand All @@ -28,12 +31,21 @@ class MyTodoFragment() : BaseFragment<FragmentMyTodoBinding>(R.layout.fragment_m
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initAddTodoListener()
setTabLayout()
setViewPager()
setTodoCountText()
observeTotalUncompletedTodoCount()
}

private fun initAddTodoListener() {
binding.btnMyTodoAddTodo.setOnSingleClickListener {
Intent(activity, MyTodoCreateActivity::class.java).apply {
startActivity(this)
}
}
}

private fun setTabLayout() {
binding.tabMyTodo.apply {
for (tabName in tabTextList) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package com.going.presentation.todo.mytodo.create

import android.graphics.drawable.Drawable
import android.os.Bundle
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.content.res.ResourcesCompat
import com.going.presentation.R
import com.going.presentation.databinding.ActivityMyTodoCreateBinding
import com.going.ui.base.BaseActivity
import com.going.ui.extension.setOnSingleClickListener

class MyTodoCreateActivity :
BaseActivity<ActivityMyTodoCreateBinding>(R.layout.activity_my_todo_create) {

private val viewModel by viewModels<MyTodoCreateViewModel>()

private var myTodoCreateBottomSheet: MyTodoCreateBottomSheet? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initViewModel()
initTodoFocusListener()
initMemoFocusListener()
initDateClickListener()
initFinishBtnListener()
initBackBtnListener()
observeTextLength()
observeMemoLength()
observeDateEmpty()
}

private fun initViewModel() {
binding.vm = viewModel
}

private fun initTodoFocusListener() {
binding.etMyTodoCreateTodo.setOnFocusChangeListener { _, hasFocus ->
setColors(
hasFocus,
viewModel.nowTodoLength.value ?: 0,
binding.tvMyTodoTodoCounter,
) { background ->
binding.etMyTodoCreateTodo.background = setBackgroundColor(background)
}
}
}

private fun initMemoFocusListener() {
binding.etMyTodoCreateMemo.setOnFocusChangeListener { _, hasFocus ->
setColors(
hasFocus,
viewModel.nowMemoLength.value ?: 0,
binding.tvMyTodoMemoCounter,
) { background ->
binding.etMyTodoCreateMemo.background = setBackgroundColor(background)
}
}
}

private fun initDateClickListener() {
binding.etMyTodoCreateDate.setOnSingleClickListener {
myTodoCreateBottomSheet = MyTodoCreateBottomSheet()
myTodoCreateBottomSheet?.show(supportFragmentManager, DATE_BOTTOM_SHEET)
}
}

private fun initFinishBtnListener() {
binding.btnMyTodoMemoFinish.setOnSingleClickListener {
// 서버통신 진행
finish()
}
}

private fun initBackBtnListener() {
binding.btnMyTodoCreateBack.setOnSingleClickListener {
finish()
}
}

private fun observeTextLength() {
viewModel.nowTodoLength.observe(this) { length ->
val maxTodoLen = viewModel.getMaxTodoLen()

if (length > maxTodoLen) {
binding.etMyTodoCreateTodo.apply {
setText(text?.subSequence(0, maxTodoLen))
setSelection(maxTodoLen)
}
}
setColors(
false,
viewModel.nowTodoLength.value ?: 0,
binding.tvMyTodoTodoCounter,
) { background ->
binding.etMyTodoCreateTodo.background = setBackgroundColor(background)
}
}
}

private fun observeMemoLength() {
viewModel.nowMemoLength.observe(this) { length ->
val maxMemoLen = viewModel.getMaxMemoLen()
if (length > maxMemoLen) {
binding.etMyTodoCreateTodo.apply {
setText(text?.subSequence(0, maxMemoLen))
setSelection(maxMemoLen)
}
}
setColors(
false,
viewModel.nowMemoLength.value ?: 0,
binding.tvMyTodoMemoCounter,
) { background ->
binding.etMyTodoCreateMemo.background = setBackgroundColor(background)
}
}
}

private fun observeDateEmpty() {
viewModel.endDate.observe(this) { text ->
if (text.isEmpty()) {
binding.etMyTodoCreateDate.setBackgroundResource(R.drawable.shape_rect_4_gray200_line)
} else {
binding.etMyTodoCreateDate.setBackgroundResource(R.drawable.shape_rect_4_gray700_line)
}
}
}

private fun setColors(
hasFocus: Boolean,
length: Int,
counter: TextView,
setBackground: (Int) -> Unit,
) {
val (color, background) = when {
hasFocus || viewModel.nowTodoLength.value != 0 -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
length == 0 -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
else -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
}
setCounterColor(counter, color)
setBackground(background)
}

private fun setCounterColor(counter: TextView, color: Int) {
counter.setTextColor(getColor(color))
}

private fun setBackgroundColor(background: Int): Drawable? {
return ResourcesCompat.getDrawable(
this.resources,
background,
theme,
)
}

override fun onDestroy() {
super.onDestroy()
if (myTodoCreateBottomSheet?.isAdded == true) myTodoCreateBottomSheet?.dismiss()
}

companion object {
private const val DATE_BOTTOM_SHEET = "DATE_BOTTOM_SHEET"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.going.presentation.todo.mytodo.create

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import com.going.presentation.R
import com.going.presentation.databinding.FragmentMyTodoCreateBottomSheetBinding
import com.going.ui.base.BaseBottomSheet
import com.going.ui.extension.setOnSingleClickListener

class MyTodoCreateBottomSheet() :
BaseBottomSheet<FragmentMyTodoCreateBottomSheetBinding>(R.layout.fragment_my_todo_create_bottom_sheet) {

private val viewModel by activityViewModels<MyTodoCreateViewModel>()

override fun onStart() {
super.onStart()
dialog?.window?.setBackgroundDrawableResource(R.color.transparent)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initFinishBtnClickListener()
}

private fun initFinishBtnClickListener() {
binding.btnCreateTripFinish.setOnSingleClickListener {
viewModel.endDate.value =
binding.dpCreateTripDate.year.toString() + "." + (binding.dpCreateTripDate.month + 1).toString() + "." + binding.dpCreateTripDate.dayOfMonth.toString()
viewModel.checkIsFinishAvailable()
Comment on lines +29 to +31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string 리소스 내부 변수를 활용해서 나타낸다면 더 좋을 것 같아요~
string 리소스를 "%1d.%2d.%3d"이렇게 두고 해당 값들을 변수로 넣으면 좋을 것 같네용!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

귀차나요

dismiss()
Comment on lines +27 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 깔꼼하네요 좋습니다아

}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.going.presentation.todo.mytodo.create

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import java.text.BreakIterator

class MyTodoCreateViewModel : ViewModel() {

val todo = MutableLiveData("")
val nowTodoLength = MutableLiveData(0)

val endDate = MutableLiveData("")

val memo = MutableLiveData("")
val nowMemoLength = MutableLiveData(0)

val isFinishAvailable = MutableLiveData(false)

fun getMaxTodoLen() = MAX_TODO_LEN

fun getMaxMemoLen() = MAX_MEMO_LEN

fun checkIsFinishAvailable() {
nowTodoLength.value = getGraphemeLength(todo.value)
nowMemoLength.value = getGraphemeLength(memo.value)
isFinishAvailable.value =
todo.value?.isNotEmpty() == true && memo.value?.isNotEmpty() == true && endDate.value?.isNotEmpty() == true
}

// 이모지 포함 글자 수 세는 함수
private fun getGraphemeLength(value: String?): Int {
BREAK_ITERATOR.setText(value)
var count = 0
while (BREAK_ITERATOR.next() != BreakIterator.DONE) {
count++
}
return count
}

companion object {
val BREAK_ITERATOR: BreakIterator = BreakIterator.getCharacterInstance()

const val MAX_TODO_LEN = 15
const val MAX_MEMO_LEN = 1000
}

}
9 changes: 9 additions & 0 deletions presentation/src/main/res/drawable/ic_dropdown.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.264,16.205C11.659,16.633 12.337,16.633 12.733,16.205L17.376,11.179C17.967,10.538 17.513,9.5 16.641,9.5H7.355C6.483,9.5 6.029,10.538 6.62,11.179L11.264,16.205Z"
android:fillColor="#C3C4CE"/>
</vector>
14 changes: 14 additions & 0 deletions presentation/src/main/res/drawable/ic_lock_my_todo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<group>
<clip-path
android:pathData="M0,0h12v12h-12z"/>
<path
android:pathData="M8.5,4.333H9C9.55,4.333 10,4.762 10,5.286V10.048C10,10.571 9.55,11 9,11H3C2.45,11 2,10.571 2,10.048V5.286C2,4.762 2.45,4.333 3,4.333H3.5V3.381C3.5,2.067 4.62,1 6,1C7.38,1 8.5,2.067 8.5,3.381V4.333ZM4.45,4.333H7.55V3.381C7.55,2.567 6.855,1.905 6,1.905C5.145,1.905 4.45,2.567 4.45,3.381V4.333Z"
android:fillColor="#FF4F17"
android:fillType="evenOdd"/>
</group>
</vector>
Loading