RiverMoon Tech Blog
  • [Android] Using Kotlin & MVVM Architecture
    2023년 07월 12일 10시 05분 31초에 업로드 된 글입니다.
    작성자: Moonsu99

    [Skills]

    Languages Kotlin
    Architecture MVVM
    Jetpack LiveData, DataBinding, ViewModel
    Local DB SharedPreferences
    Image Glide
    DI Hilt
    Cloud Platform FireBase

     

    [Implementation of this posting]

    1. Create a project.

    2. Connect to Firebase.

    3. Login, registration page UI.

    4. Implementing login and registration functions.

    5. Create a fragment pages.

     

    [Implementation screen]

    Login Screen & Register Screen
    Fragment

     

     

     

    1. Create a project(Empty Activity) MIN API-28.

     

    2. Connecting to FireBase.

    https://rivermoon99.tistory.com/14

     

    [Android Kotlin Connecting to Firebase]

    1. Access to Firebase.(https://firebase.google.com/) 2. Click "Get started" and Login 3. Click "Add project" Fill in the project name and click the Continue button.(Any project name is fine) Check "Enable Google Analytics for this project" and click the Co

    rivermoon99.tistory.com

     

    3. Configuring packages for MVVM architecture.

    Todo List's packages

    Data
    api Contains an API interface for communication with external services. For example, you can include an interface responsible for communicating with Firebase.
    model Defines a data model class. For example, include the data structure of Todo entries.
    repository It is responsible for interacting with data sources. For example, it manages communication with the Firebase Realtime Database and handles CRUD operations for data.
    Ui
    base Define a base class that contains the app's basic UI components or common logic.
    adapter Contains the adapter class used to display lists, such as RecyclerView or ListView.
    view Define screen elements, such as activities or fragments. Responsible for UI shown to users.
    viewmodel Contains ViewModel classes. Acts as a mediator between View (Activity or Fragment) and Model
     
    utils Contains utility classes or helper functions commonly used by applications. For example, you can implement features such as converting date formats and checking network status.

     

    4. create the Login page and the Register page UI.

     

    [activity_login.xml]

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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"
        android:orientation="vertical"
        android:backgroundTint="@color/white"
         tools:context=".ui.main.view.LoginActivity">
        <LinearLayout
            android:layout_weight="3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="To Do List"
                android:textSize="30sp"
                android:textColor="@color/black"
                android:fontFamily="@font/ths"/>
        </LinearLayout>
                <LinearLayout
                    android:layout_weight="1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
                    <EditText
                        android:id="@+id/input_email"
                        android:background="@drawable/edit_radius_round"
                        android:layout_marginHorizontal="15dp"
                        android:layout_marginBottom="10dp"
                        android:layout_width="match_parent"
                        android:layout_height="48dp"
                        android:fontFamily="@font/ths"
                        android:drawableStart="@drawable/baseline_perm_identity_24"
                        android:hint="Input E-Mail"/>
                    <EditText
                        android:id="@+id/input_password"
                        android:background="@drawable/edit_radius_round"
                        android:layout_marginHorizontal="15dp"
                        android:layout_width="match_parent"
                        android:layout_height="48dp"
                        android:fontFamily="@font/ths"
                        android:drawableStart="@drawable/baseline_password_24"
                        android:inputType="textPassword"
                        android:hint="Input Password"/>
                    <android.widget.Button
                        android:id="@+id/btn_Login"
                        android:layout_marginTop="20dp"
                        android:background="@drawable/login_button_clicked"
                        android:layout_marginHorizontal="15dp"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textColor="@color/black"
                        android:text="Go Todo"/>
                </LinearLayout>
                            <LinearLayout
                                android:layout_weight="1"
                                android:layout_marginTop="20dp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:orientation="vertical">
                                <TextView
                                    android:id="@+id/go_Register"
                                    android:gravity="center"
                                    android:clickable="true"
                                    android:layout_width="match_parent"
                                    android:layout_height="48dp"
                                    android:textColor="@color/black"
                                    android:text="Register"
                                    android:fontFamily="@font/ths"
                                    android:textSize="15sp"/>
                                <TextView
                                    android:gravity="center"
                                    android:clickable="true"
                                    android:layout_width="match_parent"
                                    android:layout_height="48dp"
                                    android:textColor="@color/black"
                                    android:text="Forgot Password?"
                                    android:fontFamily="@font/ths"
                                    android:textSize="15sp"/>
                            </LinearLayout>
    </LinearLayout>

     

    [activity_register.xml]

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:backgroundTint="@color/white"
        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"
        android:orientation="vertical"
        tools:context=".ui.main.view.RegisterActivity">
            <LinearLayout
                android:layout_weight="1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginHorizontal="10dp"
                android:layout_marginTop="10dp"
                android:orientation="vertical">
                    <ImageButton
                        android:id="@+id/back_btn"
                        android:layout_width="48dp"
                        android:layout_height="48dp"
                        android:src="@drawable/baseline_arrow_back_24"
                        android:background="@null"/>
                    <TextView
                        android:layout_marginTop="20dp"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="REGISTER"
                        android:textColor="@color/black"
                        android:fontFamily="@font/ths"
                        android:textSize="30sp"
                        android:gravity="center"/>
                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="E-Mail"
                            android:textColor="@color/black"
                            android:textStyle="bold"
                            android:textSize="15sp"/>
                        <EditText
                            android:id="@+id/edit_Email"
                            android:drawableStart="@drawable/baseline_email_24"
                            android:layout_width="match_parent"
                            android:layout_height="48dp"
                            android:textSize="15sp"
                            android:hint="Input E-Mail"/>
                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:text="Password"
                                android:textColor="@color/black"
                                android:textStyle="bold"
                                android:textSize="15sp"/>
                            <EditText
                                android:id="@+id/edit_Password"
                                android:drawableStart="@drawable/baseline_password_24"
                                android:layout_width="match_parent"
                                android:layout_height="48dp"
                                android:textSize="15sp"
                                android:inputType="textPassword"
                                android:hint="Input Password"/>
                                <TextView
                                    android:layout_width="match_parent"
                                    android:layout_height="wrap_content"
                                    android:text="Nickname"
                                    android:textColor="@color/black"
                                    android:textStyle="bold"
                                    android:textSize="15sp"/>
                                <EditText
                                    android:id="@+id/edit_Nickname"
                                    android:drawableStart="@drawable/nickname_icon"
                                    android:layout_width="match_parent"
                                    android:layout_height="48dp"
                                    android:textSize="15sp"
                                    android:hint="Input Nickname"/>
                                    <TextView
                                        android:layout_width="match_parent"
                                        android:layout_height="wrap_content"
                                        android:text="Name"
                                        android:textColor="@color/black"
                                        android:textStyle="bold"
                                        android:textSize="15sp"/>
                                    <EditText
                                        android:id="@+id/edit_Name"
                                        android:drawableStart="@drawable/baseline_perm_identity_24"
                                        android:layout_width="match_parent"
                                        android:layout_height="48dp"
                                        android:textSize="15sp"
                                        android:hint="Input Name"/>
                                            <LinearLayout
                                                android:layout_width="match_parent"
                                                android:layout_height="wrap_content"
                                                android:layout_weight="1"
                                                android:gravity="bottom"
                                                android:layout_marginBottom="20dp"
                                                android:orientation="vertical">
                                            <android.widget.Button
                                                android:id="@+id/btn_Register"
                                                android:background="@drawable/login_button_clicked"
                                                android:layout_marginHorizontal="35dp"
                                                android:layout_width="match_parent"
                                                android:layout_height="wrap_content"
                                                android:textColor="@color/black"
                                                android:text="Register"/>
                                            </LinearLayout>
            </LinearLayout>
    </LinearLayout>

     

    5. Login and Registeration function implementation.

     

    Now, Let's going to fill out the Kotlin file.

    I think it's best to write it in the order of model → api repository viewmodel ui utils.

    I can't write down all the codes, so I'll just describe them briefly. I will post the detailed code on GitHub.

     

    The files for login and register are as follows.
    Authapi.kt, FirebaseAuthapi.kt, User.kt, Authrepository.kt, LoginActivity.kt, RegisterActivity.kt, RegisterViewModel, InputValidator.kt

    user.kt data model class
    Authapi.kt Includes an interface for interacting with Firebase Authentication. API call method definition related to membership
    AuthRepository.kt this file is a repository class that interacts with the data sources associated with membership registration. Manage communications with Firebase Authentication and handle register logic.
    RegisterViewModel.kt this file is a ViewModel class associated with the register screen. It acts as a mediator between View (Activity or Fragment) and Model (repository), processes user input, and executes register logic.


    6. Creating a fragment.

     

    1. Create one HomeActivity(parent)

    In HomeActivity, it consists of a navigation bar and a frame layout that can move fragments.

    You should also create a menu file for navigation.

     

    [menu.xml]

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:title="Main"
            android:id="@+id/home"
            android:icon="@drawable/dashboard"/>
        <item android:title="Cal"
            android:id="@+id/calendar"
            android:icon="@drawable/calendar"/>
        <item android:title="Acc"
            android:id="@+id/account_Book"
            android:icon="@drawable/account"/>
        <item android:title="CList"
            android:id="@+id/check_List"
            android:icon="@drawable/checklist"/>
    </menu>

     

    [activity_home.xml]

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_menu"
        style="@style/BottomNavigationView">
    </com.google.android.material.bottomnavigation.BottomNavigationView>

     

    [HomeActivity.kt]

    class HomeActivity : AppCompatActivity() {
    
        private lateinit var binding: ActivityHomeBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityHomeBinding.inflate(layoutInflater)
            setContentView(binding.root)
            replaceFragment(HomeFragment())
            window.statusBarColor = Color.parseColor("#000000")
            binding.bottomNavigationView.setOnItemSelectedListener {
                when(it.itemId){
                    R.id.home -> replaceFragment(HomeFragment())
                    R.id.calendar -> replaceFragment(CalendarFragment())
                    R.id.account_Book -> replaceFragment(AccountFragment())
                    R.id.check_List -> replaceFragment(CheckFragment())
                    else ->{
    
                    }
                }
                true
            }
        }
        private fun replaceFragment(fragment: Fragment){
            val fragmentManager = supportFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()
            fragmentTransaction.replace(R.id.frame_layout,fragment)
            fragmentTransaction.commit()
        }
    }

     

    2. Right-click in layout directory  New  Fragment  Fragment(Blank)

    The initial setup of the fragment does this.(Other fragments are the same.)

     

    [HomeFragment.kt]

    class HomeFragment : Fragment() {
        lateinit var binding: FragmentHomeBinding
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            binding = FragmentHomeBinding.inflate(inflater, container, false)
            // ActionBar hide
            (activity as AppCompatActivity).supportActionBar?.hide()
    
            return binding.root
        }
    }

     

     

     

    That's the end of this post. The next post will be using the Google calendar API and overall UI configuration. Thanks.

     

    댓글