코틀린 fragment 화면 전환시 이전 화면 유지하기
2023. 12. 17. 18:46ㆍ- 안드로이드/kotlin
fragment를 사용한 바텀 네비게이션에서 화면을 전환하고 다시 원래 화면으로 돌아오면 화면이 유지 되지 않고 초기화 되는 문제점이 발견되었습니다. 이번 포스팅에서 화면 전환을 해도 fragment가 유지 되도록 코드를 짜보겠습니다.
먼저 fragment xml을 만들어 줍니다.
fragment_monitoring.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.MonitoringFragment">
<TextView
android:id="@+id/textViewTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="모니터링"
android:layout_centerInParent="true"/>
<Button
android:id="@+id/buttonTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="버튼"/>
</RelativeLayout>
MonitoringFragment.class
class MonitoringFragment : Fragment() {
private var mBinding: FragmentMonitoringBinding? = null
private val binding get() = mBinding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mBinding = FragmentMonitoringBinding.inflate(inflater, container, false)
binding.buttonTest.setOnClickListener {
binding.textViewTest.text = "클릭됨"
}
return binding.root
}
override fun onDestroyView() {
mBinding = null
super.onDestroyView()
}
}
위와 같은 방식으로 필요한 페이지의 프래그 먼트를 만들어 줍니다.
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ActivityMain">
<FrameLayout android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/fragmentHost"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/bottomNavi"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.BottomNavigationView.PrimarySurface"
app:menu="@menu/navi_menu"
android:clickable="false"
app:itemIconTint="@drawable/menu_click_color"
app:itemTextColor="@drawable/menu_click_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
ActivityMain.class
class ActivityMain : AppCompatActivity() {
private var mBinding: ActivityMainBinding? = null
private val binding get() = mBinding!!
private val fragmentManager = supportFragmentManager
private var monitoringFragment: MonitoringFragment? = null
private var analysisFragment: AnalysisFragment? = null
private var premiumFragment: PremiumFragment? = null
private var profileFragment: ProfileFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.bottomNavi.labelVisibilityMode = LABEL_VISIBILITY_LABELED // label 항상 보이기
initBottomNavigation()
}
private fun initBottomNavigation(){
// 최초로 보이는 프래그먼트
monitoringFragment = MonitoringFragment()
fragmentManager.beginTransaction().replace(R.id.fragmentHost,monitoringFragment!!).commit()
binding.bottomNavi.setOnItemSelectedListener {
when(it.itemId){
R.id.monitoringFragment ->{
if(monitoringFragment == null){ // null일때만 한번 만들고 이후에는 생성된 객체를 사용하기 때문에 초기화 안됨
monitoringFragment = MonitoringFragment()
fragmentManager.beginTransaction().add(R.id.fragmentHost,monitoringFragment!!).commit()
}
if(monitoringFragment != null) fragmentManager.beginTransaction().show(monitoringFragment!!).commit()
if(analysisFragment != null) fragmentManager.beginTransaction().hide(analysisFragment!!).commit()
if(premiumFragment != null) fragmentManager.beginTransaction().hide(premiumFragment!!).commit()
if(profileFragment != null) fragmentManager.beginTransaction().hide(profileFragment!!).commit()
return@setOnItemSelectedListener true
}
R.id.analysisFragment ->{
if(analysisFragment == null){
analysisFragment = AnalysisFragment()
fragmentManager.beginTransaction().add(R.id.fragmentHost,analysisFragment!!).commit()
}
if(monitoringFragment != null) fragmentManager.beginTransaction().hide(monitoringFragment!!).commit()
if(analysisFragment != null) fragmentManager.beginTransaction().show(analysisFragment!!).commit()
if(premiumFragment != null) fragmentManager.beginTransaction().hide(premiumFragment!!).commit()
if(profileFragment != null) fragmentManager.beginTransaction().hide(profileFragment!!).commit()
return@setOnItemSelectedListener true
}
R.id.premiumFragment ->{
if(premiumFragment == null){
premiumFragment = PremiumFragment()
fragmentManager.beginTransaction().add(R.id.fragmentHost,premiumFragment!!).commit()
}
if(monitoringFragment != null) fragmentManager.beginTransaction().hide(monitoringFragment!!).commit()
if(analysisFragment != null) fragmentManager.beginTransaction().hide(analysisFragment!!).commit()
if(premiumFragment != null) fragmentManager.beginTransaction().show(premiumFragment!!).commit()
if(profileFragment != null) fragmentManager.beginTransaction().hide(profileFragment!!).commit()
return@setOnItemSelectedListener true
}
R.id.profileFragment ->{
if(profileFragment == null){
profileFragment = ProfileFragment()
fragmentManager.beginTransaction().add(R.id.fragmentHost,profileFragment!!).commit()
}
if(monitoringFragment != null) fragmentManager.beginTransaction().hide(monitoringFragment!!).commit()
if(analysisFragment != null) fragmentManager.beginTransaction().hide(analysisFragment!!).commit()
if(premiumFragment != null) fragmentManager.beginTransaction().hide(premiumFragment!!).commit()
if(profileFragment != null) fragmentManager.beginTransaction().show(profileFragment!!).commit()
return@setOnItemSelectedListener true
}
else ->{
return@setOnItemSelectedListener true
}
}
}
}
}
각 프래그먼트 monitoringFragment등을 지역변수가 아닌 멤버변수로 생성하여 데이터를 유지 하도록 합니다. 각 프래그먼트 객체 생성은 null일 경우에 한번만 생성 하고 null이 아니라면 기존에 생성 했던 프래그먼트를 재사용 하며 화면을 유지 할 수 있습니다.
'- 안드로이드 > kotlin' 카테고리의 다른 글
코틀린 안드로이드 스튜디오 다크모드 비활성화 (0) | 2024.01.10 |
---|---|
코틀린 retrofit2 레트로핏2 사용하기 (0) | 2024.01.04 |
getLaunchIntentForPackage로 다른앱 실행시키기 (0) | 2023.12.06 |
코틀린 뷰 바인딩 view binding 사용하기 (0) | 2023.12.06 |
코틀린 버튼 클릭 효과주기 (0) | 2023.11.01 |