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나와 함께 루틴을 만들어볼까?
행복루틴