메인 - 하단 탭 추가

This commit is contained in:
klaus 2023-07-24 06:15:06 +09:00
parent 41c6228af5
commit d60eb7e408
33 changed files with 452 additions and 15 deletions

View File

@ -0,0 +1,9 @@
package kr.co.vividnext.sodalive.content.main
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.databinding.FragmentContentMainBinding
class ContentMainFragment : BaseFragment<FragmentContentMainBinding>(
FragmentContentMainBinding::inflate
) {
}

View File

@ -4,6 +4,7 @@ import android.content.Context
import com.google.gson.GsonBuilder
import kr.co.vividnext.sodalive.BuildConfig
import kr.co.vividnext.sodalive.common.ApiBuilder
import kr.co.vividnext.sodalive.main.MainViewModel
import kr.co.vividnext.sodalive.network.TokenAuthenticator
import kr.co.vividnext.sodalive.settings.TermsApi
import kr.co.vividnext.sodalive.settings.TermsRepository
@ -64,6 +65,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { SignUpViewModel(get()) }
viewModel { TermsViewModel(get()) }
viewModel { FindPasswordViewModel(get()) }
viewModel { MainViewModel() }
}
private val repositoryModule = module {

View File

@ -0,0 +1,9 @@
package kr.co.vividnext.sodalive.explorer
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.databinding.FragmentExplorerBinding
class ExplorerFragment : BaseFragment<FragmentExplorerBinding>(
FragmentExplorerBinding::inflate
) {
}

View File

@ -0,0 +1,7 @@
package kr.co.vividnext.sodalive.live
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
}

View File

@ -1,8 +1,183 @@
package kr.co.vividnext.sodalive.main
import android.content.res.ColorStateList
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.content.main.ContentMainFragment
import kr.co.vividnext.sodalive.databinding.ActivityMainBinding
import kr.co.vividnext.sodalive.databinding.ItemMainTabBinding
import kr.co.vividnext.sodalive.explorer.ExplorerFragment
import kr.co.vividnext.sodalive.live.LiveFragment
import kr.co.vividnext.sodalive.message.MessageFragment
import kr.co.vividnext.sodalive.mypage.MyPageFragment
import org.koin.android.ext.android.inject
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {
override fun setupView() {}
private val viewModel: MainViewModel by inject()
private lateinit var liveFragment: LiveFragment
private lateinit var loadingDialog: LoadingDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupBottomTabLayout()
}
override fun setupView() {
loadingDialog = LoadingDialog(this, layoutInflater)
liveFragment = LiveFragment()
}
private fun setupBottomTabLayout() {
setupTab(
binding = binding.tabContent,
title = "콘텐츠",
imageSrc = R.drawable.ic_tabbar_content,
colorStateList = ContextCompat.getColorStateList(
applicationContext,
R.color.color_tabbar_title
),
tab = MainViewModel.CurrentTab.CONTENT
)
setupTab(
binding = binding.tabSuda,
title = "라이브",
imageSrc = R.drawable.ic_tabbar_live,
colorStateList = ContextCompat.getColorStateList(
applicationContext,
R.color.color_tabbar_title
),
tab = MainViewModel.CurrentTab.LIVE
)
setupTab(
binding = binding.tabExplorer,
title = "탐색",
imageSrc = R.drawable.ic_tabbar_explorer,
colorStateList = ContextCompat.getColorStateList(
applicationContext,
R.color.color_tabbar_title
),
tab = MainViewModel.CurrentTab.EXPLORER
)
setupTab(
binding = binding.tabMessage,
title = "메시지",
imageSrc = R.drawable.ic_tabbar_message,
colorStateList = ContextCompat.getColorStateList(
applicationContext,
R.color.color_tabbar_title
),
tab = MainViewModel.CurrentTab.MESSAGE
)
setupTab(
binding = binding.tabMy,
title = "마이",
imageSrc = R.drawable.ic_tabbar_my,
colorStateList = ContextCompat.getColorStateList(
applicationContext,
R.color.color_tabbar_title
),
tab = MainViewModel.CurrentTab.MY
)
viewModel.currentTab.observe(this) {
setTabSelected(binding.tabContent, isSelected = false)
setTabSelected(binding.tabSuda, isSelected = false)
setTabSelected(binding.tabExplorer, isSelected = false)
setTabSelected(binding.tabMessage, isSelected = false)
setTabSelected(binding.tabMy, isSelected = false)
changeFragment(it)
when (it) {
MainViewModel.CurrentTab.CONTENT -> {
setTabSelected(binding.tabContent, isSelected = true)
}
MainViewModel.CurrentTab.LIVE -> {
setTabSelected(binding.tabSuda, isSelected = true)
}
MainViewModel.CurrentTab.EXPLORER -> {
setTabSelected(binding.tabExplorer, isSelected = true)
}
MainViewModel.CurrentTab.MESSAGE -> {
setTabSelected(binding.tabMessage, isSelected = true)
}
MainViewModel.CurrentTab.MY -> {
setTabSelected(binding.tabMy, isSelected = true)
}
else -> {
}
}
}
}
private fun setupTab(
binding: ItemMainTabBinding,
title: String,
imageSrc: Int,
colorStateList: ColorStateList?,
tab: MainViewModel.CurrentTab
) {
binding.tvTab.text = title
binding.tvTab.setTextColor(colorStateList)
binding.ivTab.setImageResource(imageSrc)
binding.root.setOnClickListener { viewModel.clickTab(tab) }
}
private fun setTabSelected(binding: ItemMainTabBinding, isSelected: Boolean) {
binding.tvTab.isSelected = isSelected
binding.ivTab.isSelected = isSelected
val fontRes = if (isSelected) {
R.font.gmarket_sans_bold
} else {
R.font.gmarket_sans_light
}
binding.tvTab.typeface = ResourcesCompat.getFont(applicationContext, fontRes)
}
private fun changeFragment(currentTab: MainViewModel.CurrentTab) {
val tag = currentTab.toString()
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
val currentFragment = fragmentManager.primaryNavigationFragment
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment)
}
var fragment = fragmentManager.findFragmentByTag(tag)
if (fragment == null) {
fragment = when (currentTab) {
MainViewModel.CurrentTab.LIVE -> liveFragment
MainViewModel.CurrentTab.CONTENT -> ContentMainFragment()
MainViewModel.CurrentTab.EXPLORER -> ExplorerFragment()
MainViewModel.CurrentTab.MESSAGE -> MessageFragment()
MainViewModel.CurrentTab.MY -> MyPageFragment()
}
fragmentTransaction.add(R.id.fl_container, fragment, tag)
} else {
fragmentTransaction.show(fragment)
}
fragmentTransaction.setPrimaryNavigationFragment(fragment)
fragmentTransaction.setReorderingAllowed(true)
fragmentTransaction.commitNow()
}
}

View File

@ -0,0 +1,35 @@
package kr.co.vividnext.sodalive.main
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.base.BaseViewModel
class MainViewModel : BaseViewModel() {
enum class CurrentTab {
@SerializedName("CONTENT")
CONTENT,
@SerializedName("LIVE")
LIVE,
@SerializedName("EXPLORER")
EXPLORER,
@SerializedName("MESSAGE")
MESSAGE,
@SerializedName("MY")
MY
}
private val _currentTab = MutableLiveData(CurrentTab.LIVE)
val currentTab: LiveData<CurrentTab>
get() = _currentTab
fun clickTab(tab: CurrentTab) {
if (_currentTab.value != tab) {
_currentTab.postValue(tab)
}
}
}

View File

@ -0,0 +1,7 @@
package kr.co.vividnext.sodalive.message
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.databinding.FragmentMessageBinding
class MessageFragment : BaseFragment<FragmentMessageBinding>(FragmentMessageBinding::inflate) {
}

View File

@ -0,0 +1,7 @@
package kr.co.vividnext.sodalive.mypage
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.databinding.FragmentMyBinding
class MyPageFragment : BaseFragment<FragmentMyBinding>(FragmentMyBinding::inflate) {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/color_eeeeee" android:state_checked="false" />
<item android:color="@color/color_9970ff" android:state_checked="true" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/color_909090" android:state_selected="false" />
<item android:color="@color/color_9970ff" android:state_selected="true" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_tabbar_content_normal" android:state_selected="false" />
<item android:drawable="@drawable/ic_tabbar_content_selected" android:state_selected="true" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_tabbar_explorer_normal" android:state_selected="false" />
<item android:drawable="@drawable/ic_tabbar_explorer_selected" android:state_selected="true" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_tabbar_live_normal" android:state_selected="false" />
<item android:drawable="@drawable/ic_tabbar_live_selected" android:state_selected="true" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_tabbar_message_normal" android:state_selected="false" />
<item android:drawable="@drawable/ic_tabbar_message_selected" android:state_selected="true" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_tabbar_my_normal" android:state_selected="false" />
<item android:drawable="@drawable/ic_tabbar_my_selected" android:state_selected="true" />
</selector>

View File

@ -1,19 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".main.MainActivity">
android:background="@color/black">
<TextView
android:layout_width="wrap_content"
<FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@+id/ll_tab"
android:layout_alignParentTop="true" />
<LinearLayout
android:id="@+id/ll_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"
android:fontFamily="@font/gmarket_sans_bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:layout_alignParentBottom="true"
android:background="@color/color_111111"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingVertical="10dp"
app:labelVisibilityMode="labeled">
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/tab_suda"
layout="@layout/item_main_tab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include
android:id="@+id/tab_content"
layout="@layout/item_main_tab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include
android:id="@+id/tab_explorer"
layout="@layout/item_main_tab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include
android:id="@+id/tab_message"
layout="@layout/item_main_tab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include
android:id="@+id/tab_my"
layout="@layout/item_main_tab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="콘텐츠"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="탐색"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="라이브"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="메시지"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="마이페이지"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
tools:src="@drawable/ic_tabbar_live" />
<TextView
android:id="@+id/tv_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="10sp"
android:fontFamily="@font/gmarket_sans_light"
tools:ignore="SmallSp"
tools:text="라이브" />
</LinearLayout>

View File

@ -10,8 +10,9 @@
<color name="color_222222">#222222</color>
<color name="color_909090">#909090</color>
<color name="color_3e3358">#3E3358</color>
<color name="color_b3909090">#B3909090</color>
<color name="color_a0e2ff">#A0E2FF</color>
<color name="color_ecfaff">#ECFAFF</color>
<color name="color_111111">#111111</color>
<color name="color_b3909090">#B3909090</color>
</resources>