스팀 앱 개발기 #9 - BaseActivity 클래스 정의 그리고 MainActivity 클래스에 적용

이번 포스트에서는 모든 액티비티들이 공통적으로 상속받을 BaseActivity 클래스를 정의하고 이를 MainActivity 클래스에 적용하는 과정을 보여 드리겠습니다.


BaseActivity 클래스 정의

MainActivity를 비롯하여 앞으로 만들 액티비티 클래스들은 모두 BaseActivity 클래스를 상속받게 할 예정입니다. 이 클래스에는 모든 액티비티들이 공통적으로 필요한 필드, 메소드들을 정의할 예정입니다.

abstract class BaseActivity<VDB: ViewDataBinding, VM: ViewModel>(
    @LayoutRes private val layoutResID: Int
) : AppCompatActivity() {

    protected val binding by lazy {
        DataBindingUtil.setContentView(this, layoutResID) as VDB
    }

    abstract protected val viewModel: VM

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        binding.lifecycleOwner = this
    }

}
  • abstract 키워드: 이 액티비티로 바로 화면 구현은 하지 않으므로 이 키워드 사용
  • VDB: 이 액티비티를 상속받을 하위 액티비티의 바인딩 객체의 데이터 타입
  • VM: 하위 액티비티의 뷰모델 객체의 데이터 타입
  • layoutResID: 하위 액티비티의 화면을 구성할 레이아웃 XML 파일의 ID
  • binding 필드: 데이터 바인딩 담당으로 뷰와 데이터를 연결해주는 역할 수행
  • viewModel 필드: 데이터 바인딩으로 UI와 연결할 데이터를 가지고 있고 이를 로딩 또는 저장 역할 수행

MainViewModel 클래스 정의

이 앱의 모든 화면에 기본적으로 MVVM 패턴을 적용할 예정입니다. 프래그먼트들에게는 뷰모델 클래스들이 이미 정의되어 있지만, MainActivity와 짝이 될 뷰모델 클래스는 아직 없습니. 이번에 MainViewModel 클래스를 정의합니다. 화면 구성에 변화는 아직 없으므로 이 클래스는 아무 필드나 메소드도 가지지 않습니다.

class MainViewModel : ViewModel() {
}

activity_main.xml 파일 변경

MainActivity에도 데이터 바인딩을 적용해야 하므로 activity_main.xml 파일도 변경해야 합니다. 프래그먼트들에 데이터 바인딩을 적용했을 때와 마찬가지로 최상위 요소는 layout이며, 기존 최상위 요소였던 ConstraintLayout은 그 안으로 옮깁니다.

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="?attr/actionBarSize">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/nav_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"
            android:background="?android:attr/windowBackground"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:menu="@menu/bottom_nav_menu" />

        <fragment
            android:id="@+id/nav_host_fragment_activity_main"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@id/nav_view"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/mobile_navigation" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

BaseActivity를 MainActivity의 상위 클래스로 지정

아래와 같이 MainActivity의 상위 클래스는 BaseActivity로 변경합니다. BaseActivity 클래스의 viewModel 필드는 abstract이므로 이 액티비티에서 그것을 오버라이드 해야 합니다. MainViewModel 객체를 생성해 주면 됩니다.

class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>(R.layout.activity_main) {

    override val viewModel: MainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }

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

        val navView: BottomNavigationView = binding.navView

        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_tags, R.id.navigation_profile, R.id.navigation_wallet
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

}

GitHub Commit


지난 스팀 앱 개발기

Sort:  
 2 years ago 

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Upvoted! Thank you for supporting witness @jswit.
default.jpg

Coin Marketplace

STEEM 0.21
TRX 0.24
JST 0.038
BTC 94636.84
ETH 3278.73
USDT 1.00
SBD 3.16