Giter VIP home page Giter VIP logo

mvvm-structure's Introduction

GEAR BY KOTLIN AND MVVM

structure:

Image of structure

Image of structure

buildSrc:

 Gradle Dependency Management 
 1. Create a root level directory called buildSrc
 2. Inside buildSrc create the file build.gradle.kts and enable the kotlin-dsl plugin with the snippet in build.gradle.kts.
 3. Create file Dependencies.kt for define libraries
 4. Can code build gradle by kotlin language (not implement)
example build gradle:

model:

Include all entities in project

local:

Implement Room to management database.

remote:

Implement Retrofit to get data from api

repository:

1. Handle get data from api and save in database.
2. Expose data result
1. Wrapper get data from local database and get data from api.
2. Data result always in object Resource
3. We can force always load from network or local. 

common:

1. Util class.
2. Base class.
3. views need to re-use (dialog..)
4. Extension 

app:

Main module. 
1. AndroidManifes.xml
2. Activities, Fragment, Viewmodel.
3. layout
4. Dependency injection.
5. Use case class.

Technical in used

Dependency injection: Dagger
AppComponent: with 2 modules: AppModule::class, ActivityProvider::class
  1. AppModule: with modules network, database, repository, viewModel
  2. ActivityProvider: provide activities, FragmentProvider.
1. Binding data from viewmodel to layout with two ways.
2. handle action to view (click, input text) 
add this code into root of view fragment.
    <data>
        <variable
            name="viewModel"
            type="com.example.gear_kotlin.viewmodel.ThirdFragmentViewModel" />
    </data>
- One class _fragmentName_Binding will automatic create.
Example is: ThirdFragmentBinding
And in Fragment: thirdFragmentBinding.viewModel = viewModel
Example: ThirdFragment and layout: fragment_third
File location: res/navigation
1 activity has 1 nav_graph.

navigation_graph

Actions: define action to replace fragment.
Arguments: this is safe-args, it's send data between fragments.

destinations

List fragment in graph

navigation_graph

1. After build, it will auto generate file Directions with name: fragmentName + Directions, 
    example: AppFirstFragmentDirections
2. Call action with parameter like this:
 val  action = AppFirstFragmentDirections.setParamInt(param1).setParamStr(param2)
      view.findViewById<Button>(R.id.button_first).setOnClickListener {findNavController().navigate(action)}
3. Get data from args like this:
 val safeArgs: AppSecondFragmentArgs by navArgs()
        val paramInt = safeArgs.paramInt
        val paramStr = safeArgs.paramStr      
Example: app_nav_graph

Image of ViewModel LifeCycle

- ViewModel never keep context of view (fragment, activity)
- ViewModel init by owner scope (fragment, activity) and ViewModelFactory. 
- Using LiveData to expose to Views (Fragment, Activity)
init 1 ViewModel in fragment:
1. Add DI to ViewModelModule
2.
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
3. in onViewCreated()
   viewModel = getViewModel(viewModelFactory)

LiveData

What is LiveData?
If we look at the definition form the Android website then it says:

LiveData is an observable data holder class. LiveData is lifecycle-aware, 
meaning it respects the lifecycle of other app components, such as activities, fragments, or services. 
This awareness ensures LiveData only updates app component observers that are in an active lifecycle state
1. MutableLiveData should be used only for notifying your UI when observing any data.
2. MediatorLiveData merge multi LiveData (by addSource and removeSource)
to understanding livedata: link
We have two ways to for set value for LiveData
1. livedata.value = xxx -> only set on mainthread.
2. livedata.postValue(xxx) -> can set in background thread.
example implement LiveData like above:
in ViewModel:
var toHome = MutableLiveData<Boolean>()
fun toHome(){
        toHome.value = true
    } 
and in Fragment
viewModel.toHome.observe(viewLifecycleOwner, Observer {
            if(it){
            }
        })

ROOM in module: local

AppDatabase

When we want to create 1 table we need to:
1. Create 1 file Entity
2. add class entity to AppDatabase
3. Create abstract class DAO
DAO object 
return 2 type:
1. suspend function: always use ( I will explain suspend function in Coroutines)
2. normal function return type Flow: this is new in coroutines, I have not implement yet.
Example: UserGitDao

Retrofit in module: remote

Define api in class api.
Define function call api in DataSource
example call an api in viewmodel
  private fun getUsers(forceRefresh: Boolean) = viewModelScope.launch(dispatchers.main) {
        withContext(dispatchers.io) {
            usersSource = getTopUsersUseCase()
        }
        _users.addSource(usersSource) {
            _users.value = it
        }
    }
EventBus
1. Already add by Dagger
2. @Inject EventManager for post and receive
3. Define requestCode in MessaeEvent
with receiver: register in onCreate, unregister in onStop
  @Subscribe(threadMode = ThreadMode.BACKGROUND)
    fun onMessageEvent(event: MessageEvent) { /* Do something */
    } 
    Can Subscribe with Main thread or Background.
Example With post:
    val message = Message()
    message.data = bundleOf(
        Pair("arg1", "Arg1 From App Second Fragment"),
        Pair("arg2", "Arg 2 From App Second Fragment")
      )
    eventManager.post(MessageEvent(MessageEvent.REQUEST_MOOD_RATING_DONE, message))

Coroutines

Coroutines

Coroutines offer main-safety
1. In ViewModel: using viewModelScope (viewModelScope.launch..)
2. In Activity, Fragment: using lifecycleScope (lifecycleScope.launch..)
3. Dispatchers already provide with DI
Dispatchers.IO: This Dispatcher is used to execute long-running and blocking I/O operations
Dispatchers.Main: Confines itself to the Main thread, and hence, only using one thread
Dispatchers.Default: Using CPU, core of device
Dispatchers.Unconfined: shouldn't normally be used in code.
launch (scope.launch): return Unit()
async (scope.async): return a Deferred<T>
File example Coroutines: CoroutinesUseCase.kt

WorkManager

component
Worker, WorkRequest, WorkManager, WorkStatus
Workflow

WorkerUsercase.kt

UploadWorker.kt

1. Create subclass of Worker -> Result Sucess, Failure, Retry
2. Defines Contraints:  
            .setRequiresBatteryNotLow(true)
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresCharging(true)
            .setRequiresStorageNotLow(true)
            .setRequiresDeviceIdle(true)
3. Create WorkRequest
 - OneTimeWorkRequest to run work only one time.
 - PeriodicWorkRequest  to run periodically,  set the interval between to subsequent work. (min in 15 minutes)
4. Schedule the request 
    WorkManager.getInstance().enqueue(request)  

mvvm-structure's People

Contributors

hanhmh1203 avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.