patloew / countries

An example Android app using Retrofit, Realm, Parceler, Dagger and the MVVM pattern with the data binding lib.
Other
615 stars 103 forks source link

Template Guideline #12

Open nurwin opened 6 years ago

nurwin commented 6 years ago

Hi Patloew,

I really appreciate your work for this template, and I want to learn your template, but I don't know where to get started. Would you like give me some guidelines or instruction for using this template?

thank you

LukaszLyskawa commented 6 years ago

Steps:

  1. Clone from branches Java & Java-template, or Kotlin & Kotlin-template (depending on your choice of language)
  2. Get to know the concept and folder architecture by looking up the Kotlin/Java branch
  3. Start working on the "x-template" branch to create your own app, don't be afraid to take a peek back at the sample app if you are stuck or don't know where certains things belong.

Typical workflow

I'll base further things on Kotlin, because I haven't used the Java branch - it's probably similar anyway.

For screens/fragments/list items etc, you create 3 files. So let's take a User screen (Activity and Fragment is mostly interchangeable here) as an example that's the most common.

You need UserMvvm, UserActivityand UserViewModel(the given order is significant, you can switch and create ViewModel before activity)

Start off by creating the interfaces in the UserMvvm file

This is just a "container" for two inner interfaces - just for quality of life sake to keep them "together" interface UserMvvm

Now you need a View and ViewModel

interface UserMvvm {
  interface View: MvvmView {
    //TODO methods/fields that end up in your Activity/Fragment/ViewHolder
  }

  interface ViewModel: MvvmViewModel<View> {
    //TODO methods/fields that end up in your ViewModel 
    //and are available for use in the XML under `vm.`
  }
}

Now you can create your XML layout for the activity

<layout>
  <data>
    <variable
         name="vm"
         type="{full namespace of UserMvvm.ViewModel interface}" />
  </data>
  <androidx.coordinatorlayout.widget.CoordinatorLayout>
   .....
  </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

You can continue with your Activity (UserActivity in this case)

class UserActivity : 
  // 1st generated databinding class for your XML, 2nd ViewModel interface you created before
  BaseActivity<ActivityUserBinding, UserMvvm.ViewModel>(),
  UserMvvm.View { //and this is your View interface

  //TODO implement UserMvvm.View methods/fields if needed

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setAndBindContentView(savedInstanceState, R.layout.activity_user)

    //TODO setup your action bar etc

    //TODO update your viewmodel if necessary, for example if you received some args in your intent
  }

}

Proceed with implementing the UserViewModel

@PerActivity
class UserViewModel
@Inject
constructor() : //inject stuff in the constructor that you need in the viewmodel
  BaseViewModel<UserMvvm.View>(),
  UserMvvm.ViewModel {
   //TODO implement the interface 
   //(stuff like updating the viewmodel with initial data from navigation, etc)
   //button logic, api calls, ...
   //properties used in XML ... (they need to be defined in the interface!)
}

Last thing but VERY IMPORTANT

Go to injection > components > ActivityComponent and inject your UserActivity

fun inject(activity: UserActivity)

Next is your viewmodel in injection > modules > ViewModelModule

@Binds
internal abstract fun bindUserViewModel(userViewModel: UserViewModel): UserMvvm.ViewModel

The specific Components and Modules depend on which View "type" (Activity, Fragment, ActivityViewHolder, FragmentViewHolder) you are implementing

Stuff for injecting into your viewmodels and views

Choose injection > modules > NetModule for REST APIs, or other network related stuff...

injection > modules > DataModule for data repositories...

I think by now you should get the basic idea of how it works, especially if you've worked with Dagger2 before.

Final words

I used this template in one of my project that I worked on for around half a year. It's great, especially if you need to write your app quickly, however keep in mind it was released before Android Jetpack has arrived, so it's not using some amazing things like LiveData, their ViewModel or Navigation (or even Room instead of Realm). Especially injection can be done less painfully with libs like Koin.

Since you found this repo, you were probably looking for the specific libs that are used here, and there's nothing wrong with that. Just keep in mind that Android and Kotlin is still evolving ;)

Kudos to @patloew.