Skip to content

Getting started

Alexey Ershov edited this page Mar 6, 2020 · 12 revisions

Getting Moxy

First, add the base Moxy module and the compiler module to your app/build.gradle dependencies block.

Please replace $moxyVersion with the latest version number: Bintray

Base modules integration:

Java

dependencies {
  // ...
  implementation "com.github.moxy-community:moxy:$moxyVersion"
  annotationProcessor "com.github.moxy-community:moxy-compiler:$moxyVersion"
}

Kotlin

apply plugin: 'kotlin-kapt'
// ...
dependencies {
  // ...
  implementation "com.github.moxy-community:moxy:$moxyVersion"
  kapt "com.github.moxy-community:moxy-compiler:$moxyVersion"
}

Base Moxy module provides all basic components, such as MvpPresenter, MvpView, MvpDelegate and so on.

The compiler will generate code for:

  • Presenter creation and injection
  • ViewState implementation
  • injection of ViewState to Presenter

Moxy uses Java 8 features, so you also need to specify source and target compatibility for each Module that uses Moxy:

android {
  ...
  // For Java-only projects use only this
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  // For Kotlin and mixed projects also add this
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

Default android module

For additional base view classes MvpActivity and MvpFragment add this:

implementation "com.github.moxy-community:moxy-android:$moxyVersion"

AndroidX module

If you're using AndroidX, you'll need a different implementation for MvpAppCompatActivity and MvpAppCompatFragment classes. Use this one:

implementation "com.github.moxy-community:moxy-androidx:$moxyVersion"

AppCompat module

If you are using AppCompat, you'll need MvpAppCompatActivity and MvpAppCompatFragment classes. Add this:

implementation "com.github.moxy-community:moxy-app-compat:$moxyVersion"

If you're using Google material, use MvpBottomSheetDialogFragment and add this:

implementation "com.github.moxy-community:moxy-material:$moxyVersion"

Kotlin extensions

Declare presenters in your views using property delegate:

class MyFragment: MvpFragment() {
    ...
    private val presenter by moxyPresenter { presenterProvider.get() }
    ...
}

Launch coroutines in presenter scope:

class MyPresenter : MvpPresenter<MvpView>() {
    override fun onFirstViewAttach() {
        presenterScope.launch {
            // Coroutine that will be canceled when presenter is destroyed
        }
    }
}

To use MvpDelegateHolder.moxyPresenter and MvpPresenter.presenterScope, add this:

implementation "com.github.moxy-community:moxy-ktx:$moxyVersion"

Hello world

Here is a super simple example of Moxy-powered screen:

View interface

public interface HelloWorldView extends MvpView {
    @AddToEndSingle
    void showMessage(String message);
}

Presenter

// Here we specify that this presenter works with HelloWorldView.
@InjectViewState
public class HelloWorldPresenter extends MvpPresenter<HelloWorldView> {

    public HelloWorldPresenter() {
    }

    // this method is called when a HelloWorldView implementation (HelloWorldActivity)
    // is attached to this presenter for the first time.
    @Override
    public void onFirstViewAttach() {
        // don't worry about nullability of getViewState() – it's always non-null
        getViewState().showMessage("Hello, world!");
    }
}

@InjectViewState annotation does several things:

  • generates ViewState-class for HelloWorldView
  • creates a new instance of this ViewState
  • injects this instance to HelloWorldPresenter.

View implementation

public class HelloWorldActivity extends MvpAppCompatActivity implements HelloWorldView {

    @InjectPresenter
    HelloWorldPresenter presenter;

    private TextView helloWorldTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hello_world);

        helloWorldTextView = findViewById(R.id.activity_hello_world_text_view_message);
    }

    @Override
    public void showMessage(String message) {
        helloWorldTextView.setText(message);
    }
}

HelloWorldActivity extends MvpAppCompatActivity, which handles the Activity lifecycle callbacks, so you don't have to worry about them.

@InjectPresenter handles the creation of HelloWorldPresenter and injects it to HelloWorldActivity. When the HelloWorldActivity is recreated, the same instance of HelloWorldPresenter will be retained and injected to the new instance of HelloWorldActivity.

@AddToEndSingle annotation is one of several Strategy annotations. This one means that the latest call of showMessage(...) method will be replayed after the HelloWorldActivity is recreated, so its state is restored after the configuration change, e.g. screen rotation.

Run

That's it, you're ready to build and run your project! Don't worry about communications between MVP components, Moxy does it for you. Moxy generates boilerplate code, takes care of the Android components' lifecycle. You just write your presentation logic and the beautiful UI.

Enjoy!