diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 001946af..a079bff6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,11 +19,6 @@ tools:targetApi="31"> - - @@ -33,6 +28,13 @@ + + diff --git a/app/src/main/java/com/sopetit/softie/domain/entity/Theme.kt b/app/src/main/java/com/sopetit/softie/domain/entity/Theme.kt new file mode 100644 index 00000000..52e2a422 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/domain/entity/Theme.kt @@ -0,0 +1,8 @@ +package com.sopetit.softie.domain.entity + +data class Theme( + val themeId: Int, + val name: String, + val iconImageUrl: String, + val backgroudnImageUrl: String +) diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/BearChoiceFragment.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/BearChoiceFragment.kt new file mode 100644 index 00000000..10dabb13 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/BearChoiceFragment.kt @@ -0,0 +1,29 @@ +package com.sopetit.softie.ui.onboarding + +import android.os.Bundle +import android.view.View +import androidx.lifecycle.ViewModelProvider +import com.sopetit.softie.R +import com.sopetit.softie.databinding.FragmentOnboardingChoiceBearBinding +import com.sopetit.softie.util.binding.BindingFragment + +class BearChoiceFragment : + BindingFragment(R.layout.fragment_onboarding_choice_bear) { + + private lateinit var viewModel: OnboardingViewModel + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel = ViewModelProvider(requireActivity()).get(OnboardingViewModel::class.java) + binding.viewModel = viewModel + + initChangeFragment() + } + + private fun initChangeFragment() { + binding.clOnboardingChoiceBear.setOnClickListener { + viewModel.changeBearNameChoiceView() + } + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingActivity.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingActivity.kt new file mode 100644 index 00000000..b98927c2 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingActivity.kt @@ -0,0 +1,70 @@ +package com.sopetit.softie.ui.onboarding + +import android.os.Bundle +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import com.sopetit.softie.R +import com.sopetit.softie.databinding.ActivityOnboardingBinding +import com.sopetit.softie.ui.onboarding.routinechoice.RoutineChoiceFragment +import com.sopetit.softie.ui.onboarding.themechoice.ChoiceThemeFragment +import com.sopetit.softie.util.binding.BindingActivity + +class OnboardingActivity : + BindingActivity(R.layout.activity_onboarding) { + + private val viewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding.viewModel = viewModel + + initMakeFragment() + initChangeFragment() + } + + private fun initMakeFragment() { + val currentFragment = supportFragmentManager.findFragmentById(R.id.fcv_onboarding_fragment) + if (currentFragment == null) { + viewModel.changeBearChoiceView() + supportFragmentManager.beginTransaction() + .add(R.id.fcv_onboarding_fragment, BearChoiceFragment()) + .commit() + } + } + + private fun initChangeFragment() { + initChangeRoutineChoice() + initChangeSetBearName() + initChangeThemeChoice() + } + + private fun initChangeSetBearName() { + viewModel.bearNameChoiceView.observe(this) { bearNameChoice -> + if (bearNameChoice) { + changeFragment(SetBearNameFragment()) + } + } + } + + private fun initChangeThemeChoice() { + viewModel.themeChoiceView.observe(this) { themeChoiceView -> + if (themeChoiceView) { + changeFragment(ChoiceThemeFragment()) + } + } + } + + private fun initChangeRoutineChoice() { + viewModel.routineChoiceView.observe(this) { routineChoiceView -> + if (routineChoiceView) { + changeFragment(RoutineChoiceFragment()) + } + } + } + + private fun changeFragment(fragment: Fragment) { + supportFragmentManager.beginTransaction() + .replace(R.id.fcv_onboarding_fragment, fragment) + .commit() + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingViewModel.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingViewModel.kt new file mode 100644 index 00000000..457473d9 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/OnboardingViewModel.kt @@ -0,0 +1,40 @@ +package com.sopetit.softie.ui.onboarding + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class OnboardingViewModel : ViewModel() { + + private val _bearChoiceView: MutableLiveData = MutableLiveData(false) + val bearChoiceView: LiveData + get() = _bearChoiceView + + private val _bearNameChoiceView: MutableLiveData = MutableLiveData(false) + val bearNameChoiceView: LiveData + get() = _bearNameChoiceView + + private val _themeChoiceView: MutableLiveData = MutableLiveData(false) + val themeChoiceView: LiveData + get() = _themeChoiceView + + private val _routineChoiceView: MutableLiveData = MutableLiveData(false) + val routineChoiceView: LiveData + get() = _routineChoiceView + + fun changeBearChoiceView() { + _bearChoiceView.value = true + } + + fun changeBearNameChoiceView() { + _bearNameChoiceView.value = true + } + + fun changeThemeChoiceView() { + _themeChoiceView.value = true + } + + fun changeRoutineChoiceView() { + _routineChoiceView.value = true + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/SetBearNameFragment.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/SetBearNameFragment.kt new file mode 100644 index 00000000..fa1c10ed --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/SetBearNameFragment.kt @@ -0,0 +1,29 @@ +package com.sopetit.softie.ui.onboarding + +import android.os.Bundle +import android.view.View +import androidx.lifecycle.ViewModelProvider +import com.sopetit.softie.R +import com.sopetit.softie.databinding.FragmentOnboardingSetBearNameBinding +import com.sopetit.softie.util.binding.BindingFragment + +class SetBearNameFragment : + BindingFragment(R.layout.fragment_onboarding_set_bear_name) { + + private lateinit var viewModel: OnboardingViewModel + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel = ViewModelProvider(requireActivity()).get(OnboardingViewModel::class.java) + binding.viewModel = viewModel + + initChangeFragment() + } + + private fun initChangeFragment() { + binding.clOnboardingSetBearName.setOnClickListener { + viewModel.changeThemeChoiceView() + } + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/routinechoice/RoutineChoiceFragment.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/routinechoice/RoutineChoiceFragment.kt new file mode 100644 index 00000000..5d0d4441 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/routinechoice/RoutineChoiceFragment.kt @@ -0,0 +1,15 @@ +package com.sopetit.softie.ui.onboarding.routinechoice + +import android.os.Bundle +import android.view.View +import com.sopetit.softie.R +import com.sopetit.softie.databinding.FragmentOnboardingChoiceRoutineBinding +import com.sopetit.softie.util.binding.BindingFragment + +class RoutineChoiceFragment : + BindingFragment(R.layout.fragment_onboarding_choice_routine) { + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeAdapter.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeAdapter.kt new file mode 100644 index 00000000..c544a452 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeAdapter.kt @@ -0,0 +1,38 @@ +package com.sopetit.softie.ui.onboarding.themechoice + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.sopetit.softie.databinding.ItemOnboardingChoiceThemeBinding +import com.sopetit.softie.domain.entity.Theme +import com.sopetit.softie.util.ItemDiffCallback + +class ChoiceThemeAdapter : + ListAdapter( + ItemDiffCallback( + onItemsTheSame = { old, new -> old.themeId == new.themeId }, + onContentsTheSame = { old, new -> old == new } + ) + ) { + + class ChoiceThemeViewHolder(private val binding: ItemOnboardingChoiceThemeBinding) : + RecyclerView.ViewHolder(binding.root) { + fun onBind(data: Theme) { + binding.tvThemeName.text = data.name + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChoiceThemeViewHolder { + val binding = ItemOnboardingChoiceThemeBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + return ChoiceThemeViewHolder(binding) + } + + override fun onBindViewHolder(holder: ChoiceThemeViewHolder, position: Int) { + holder.onBind(currentList[position]) + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeFragment.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeFragment.kt new file mode 100644 index 00000000..9953bff7 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeFragment.kt @@ -0,0 +1,73 @@ +package com.sopetit.softie.ui.onboarding.themechoice + +import android.os.Bundle +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.style.ForegroundColorSpan +import android.view.View +import androidx.core.content.ContextCompat +import androidx.fragment.app.viewModels +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.sopetit.softie.R +import com.sopetit.softie.databinding.FragmentOnboardingChoiceThemeBinding +import com.sopetit.softie.ui.onboarding.OnboardingViewModel +import com.sopetit.softie.util.binding.BindingFragment + +class ChoiceThemeFragment : + BindingFragment(R.layout.fragment_onboarding_choice_theme) { + + private lateinit var viewModel: OnboardingViewModel + private val themeViewModel by viewModels() + + private var _choiceThemeAdapter: ChoiceThemeAdapter? = null + private val choiceThemeAdapter + get() = requireNotNull(_choiceThemeAdapter) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel = ViewModelProvider(requireActivity()).get(OnboardingViewModel::class.java) + binding.viewModel = viewModel + + binding.tvOnboardingChoiceThemeSpeech.text = + SpannableStringBuilder(getString(R.string.onboarding_choice_theme_speech)).apply { + setSpan( + ForegroundColorSpan( + ContextCompat.getColor( + requireActivity(), + R.color.onboarding_speech + ) + ), + SPAN_START, + SPAN_END, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + + initMakeThemeAdapter() + } + + private fun initMakeThemeAdapter() { + _choiceThemeAdapter = ChoiceThemeAdapter() + binding.rvOnboardingChoiceTheme.apply { + layoutManager = GridLayoutManager(requireContext(), 3) + adapter = choiceThemeAdapter + } + themeViewModel.mockThemeList.observe(viewLifecycleOwner) { + choiceThemeAdapter.submitList(it) + } + } + + private fun initChangeFragment() { + // TODO 버튼 클릭시 '루틴 선택' fragment로 화면 전환 (밑의 주석 삭제 예정) +// binding.clOnboardingChoiceTheme.setOnClickListener { +// viewModel.changeRoutineChoiceView() +// } + } + + companion object { + const val SPAN_START = 5 + const val SPAN_END = 8 + } +} diff --git a/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeViewModel.kt b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeViewModel.kt new file mode 100644 index 00000000..eaad960c --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/ui/onboarding/themechoice/ChoiceThemeViewModel.kt @@ -0,0 +1,90 @@ +package com.sopetit.softie.ui.onboarding.themechoice + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.sopetit.softie.domain.entity.Theme + +class ChoiceThemeViewModel : ViewModel() { + + private val _mockThemeList: MutableLiveData> = MutableLiveData( + mutableListOf( + Theme( + 1, + "하루의 시작", + "", + "" + ), + Theme( + 2, + "건강한 몸", + "", + "" + ), + Theme( + 3, + "무기력 극복", + "", + "" + ), + Theme( + 4, + "편안한 잠", + "", + "" + ), + Theme( + 5, + "환경지킴이", + "", + "" + ), + Theme( + 6, + "소소한 친절", + "", + "" + ), + Theme( + 7, + "감사의 마음", + "", + "" + ), + Theme( + 8, + "작은 성취감", + "", + "" + ), + Theme( + 9, + "소중한 나", + "", + "" + ), + Theme( + 10, + "통통한 통장", + "", + "" + ), + Theme( + 11, + "몰입할 준비", + "", + "" + ), + Theme( + 12, + "비워내기", + "", + "" + ) + + ) + ) + + val mockThemeList: LiveData> + get() = _mockThemeList +} diff --git a/app/src/main/res/drawable/ic_doll_face_1.xml b/app/src/main/res/drawable/ic_doll_face_1.xml new file mode 100644 index 00000000..3c6c1e23 --- /dev/null +++ b/app/src/main/res/drawable/ic_doll_face_1.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_theme_1.xml b/app/src/main/res/drawable/ic_theme_1.xml new file mode 100644 index 00000000..71cb0d82 --- /dev/null +++ b/app/src/main/res/drawable/ic_theme_1.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/selector_onboarding_top.xml b/app/src/main/res/drawable/selector_onboarding_top.xml new file mode 100644 index 00000000..33228b9b --- /dev/null +++ b/app/src/main/res/drawable/selector_onboarding_top.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable/shape_gray100_fill_99_rect.xml b/app/src/main/res/drawable/shape_gray100_fill_99_rect.xml new file mode 100644 index 00000000..2e30d288 --- /dev/null +++ b/app/src/main/res/drawable/shape_gray100_fill_99_rect.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/shape_gray100_filll_100_circle.xml b/app/src/main/res/drawable/shape_gray100_filll_100_circle.xml new file mode 100644 index 00000000..f2fb1512 --- /dev/null +++ b/app/src/main/res/drawable/shape_gray100_filll_100_circle.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/shape_main1_fill_99_rect.xml b/app/src/main/res/drawable/shape_main1_fill_99_rect.xml new file mode 100644 index 00000000..41935d53 --- /dev/null +++ b/app/src/main/res/drawable/shape_main1_fill_99_rect.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/shape_white_fill_100_circle.xml b/app/src/main/res/drawable/shape_white_fill_100_circle.xml new file mode 100644 index 00000000..47171392 --- /dev/null +++ b/app/src/main/res/drawable/shape_white_fill_100_circle.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml new file mode 100644 index 00000000..a235f915 --- /dev/null +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_onboarding_choice_bear.xml b/app/src/main/res/layout/fragment_onboarding_choice_bear.xml new file mode 100644 index 00000000..0b68805c --- /dev/null +++ b/app/src/main/res/layout/fragment_onboarding_choice_bear.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_onboarding_choice_routine.xml b/app/src/main/res/layout/fragment_onboarding_choice_routine.xml new file mode 100644 index 00000000..fc24a761 --- /dev/null +++ b/app/src/main/res/layout/fragment_onboarding_choice_routine.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_onboarding_choice_theme.xml b/app/src/main/res/layout/fragment_onboarding_choice_theme.xml new file mode 100644 index 00000000..a4caac75 --- /dev/null +++ b/app/src/main/res/layout/fragment_onboarding_choice_theme.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_onboarding_set_bear_name.xml b/app/src/main/res/layout/fragment_onboarding_set_bear_name.xml new file mode 100644 index 00000000..9b9be10c --- /dev/null +++ b/app/src/main/res/layout/fragment_onboarding_set_bear_name.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_onboarding_choice_theme.xml b/app/src/main/res/layout/item_onboarding_choice_theme.xml new file mode 100644 index 00000000..bcc1322b --- /dev/null +++ b/app/src/main/res/layout/item_onboarding_choice_theme.xml @@ -0,0 +1,43 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a762e3fa..bf46e90a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -32,4 +32,7 @@ #FFD4BBA5 #FFC4AC98 + + + #FF259560 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 024620e8..18fce077 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,9 @@ Softie + + 다 선택했어 + 하루의 시작 + 안녕 난 애착이야!\n나와 함께 루틴을 만들어볼까? 행복루틴