A Mosby based VIPER library for Android

Overview

Moviper

A Mosby based VIPER library for Android

Why Moviper?

You got tired because of fact that your Activities and Fragments were becoming god classes, so you have migrated to MVP. Now you're tired of your god-class presenters and you just want to stop continuously wondering if you should pass a context to your presenters and make them platform-dependent and harder to mock and test, or maybe you should let your view-activity manage the system connected work. That's why you're here. My Android VIPER interpretation allows you keep your code clean, neat, and more SRP with minimal effort. You can find more info about benefits of using VIPER architecture in this article.

OK, but for every screen I have to create so many files!

To avoid manually creating all VIPER class files and managing their dependencies every time you want to create a new screen I created a generator that does all of necessary work for you. You can find it here.

Great! But I'm used to go with Mosby. What about all of its goodies?

Moviper has all of the Mosby's MVP Views mapped to fit VIPER requirements. Just simply replace Mvp with Viper and let the Android Studio do the autoimport for you.

For example MvpFragment maps to ViperFragment.

Dependency

Import the selected Moviper modules to your module gradle file. Moviper-rx 2.x.x is built on top of RxJava2. For RxJava1 legacy Moviper version 1.5.0 see below.

dependencies {
    // core modules, in the most common scenario importing one of these two will be enough
    compile 'com.mateuszkoslacz.moviper:moviper-rx:2.0.4' // RxJava communication based Moviper core (recommended)
    compile 'com.mateuszkoslacz.moviper:moviper-callbacks:2.0.4' // callbacks communication based Moviper core 
    
    // Mosby's viewstate Moviper views 
    compile 'com.mateuszkoslacz.moviper:moviper-viewstate:2.0.4'
    
    // Butterknife Moviper views
    compile 'com.mateuszkoslacz.moviper:moviper-butterknife:2.0.4'
    // Butterknife Moviper views with Mosby's viewstate
    compile 'com.mateuszkoslacz.moviper:moviper-butterknife-viewstate:2.0.4'
    
    // Databinding Moviper Views 
    compile 'com.mateuszkoslacz.moviper:moviper-databinding:2.0.4'
    // Databinding Moviper Views Mosby's viewstate
    compile 'com.mateuszkoslacz.moviper:moviper-databinding-viewstate:2.0.4'
    
    // Recyclerview Moviper extension, allows you create the Viper classes set for every RecyclerVew cell
    compile 'com.mateuszkoslacz.moviper:moviper-recyclerview:2.0.4'
    // Butterknife Moviper Recyclerview cells
    compile 'com.mateuszkoslacz.moviper:moviper-recyclerview-butterknife:2.0.4'
    // Databinding Moviper Recyclerview cells
    compile 'com.mateuszkoslacz.moviper:moviper-recyclerview-databinding:2.0.4'
    
    // Android Service Moviper extensions 
    compile 'com.mateuszkoslacz.moviper:moviper-service:2.0.4'
    
    // optional testing utils, still beta, it has to be debug-compiled and causes some minor Manifest issues on debug builds
    debugCompile 'com.mateuszkoslacz.moviper:moviper-test:2.0.4'
}

RxJava1 legacy version:

dependencies {
    // legacy, RxJava1 based versions of Moviper modules. You can use them with combination of 2.x.x modules not mentioned here
    compile 'com.mateuszkoslacz.moviper:moviper-rx:1.5.0' 
    debugCompile 'com.mateuszkoslacz.moviper:moviper-test:1.5.0'
}

If you are upgrading Moviper you should probably check out the Changelog and/or the Migration guide.

Getting started

I strongly recommend you starting with reading a step-by-step tutorial I included in this blog post.

Alternatively you can check out the samples. I recommend starting with sample-super-rx-ai for Java with RxJava and Moviper Showcase repo or sample-super-rx-ai-kotlin for Kotlin with RxJava to see the most powerful Moviper architecture classes.

After that, just create a VIPER files set in your project using Moviper Template Generator, fill up the contract, generate missing methods using Android Studio autofix and implement them. That's simple!

For more basic usage you shall check out:

Samples listing

Advanced features

Args Bundle

You can easily pass extras from your Activity or Fragment to the presenter using Moviper Args Bundle. You can check out how to use it in the Sample's FullscreenPhotoPresenter constructor and its call.

Moviper Inter-Presenter-Communication

Referenced as IPC. It's RxJava based, so it works only on the Rx-flavor of Moviper.

Sample usage available in sample-ipc

Quickstart

Enable IPC in your Application class onCreate() method.

Moviper.getInstance().setConfig(
        new Config.Builder()
                .withPresenterAccessUtilEnabled(true) // plain IPC
                .withInstancePresentersEnabled(false) // acces to specific presenters
                .build());
Plain IPC

You can access all alive Presenters of a given class from any place in your app like this:

Moviper.getInstance().getPresenters(SomePresenter.class)
        .subscribe(somePresenter -> somePresenter.someMethod(false)); // stream of all Presenters goes here

For readability mark your external methods in the Presenter using the @ExternalCall annotation.

Instance Presenters Access

If you set the withInstancePresentersEnabled in the config to true you can use Instance Presenter Access. After that you must ensure that every Presenter of given class has an unique name. To do so you have to override Presenter String getName() method (in default it returns "default").

After that you can access any Presenter Instance like this:

Moviper.getInstance().getPresenterInstance(SomePresenter.class, "someName")
        .subscribe(somePresenter -> somePresenter.someMethod(false)); // exactly one or zero Presenters with given name and class goes here

VIPER ViewHolders

need importing moviper-recyclerview module

For complex RecyclerView list elements and/or multiple views on RecyclerViewlist you can design your app in the way that treats every list element as a separate VIPER View with its own contract. Generating such ViewHolders is supported in the Moviper Template Generator. For the sample usage check out the sample-recyclerview.

Autoinject Views

AutoInject (Ai) Views that allow you to skip overriding the onCreate(...) / onViewCreated(..) method. Instead, in plain Ai Views you have to provide the layout id by overriding a getLayoutId() method and to perform any view injections, getting references to views etc. by overriding a injectViews() method. In addition, it contains the pre-baked classes, where these methods are already implemented inside of base classes for:

  • Butterknife - moviper-butterknife module (check out sample-rx-ai),
  • DataBinding -moviper-databinding module (just like in sample-super-rx-databinding, but not using passive views),
  • for Kotlin Android Extensions you shall use regular Ai Views from base module (just like in sample-super-rx-ai-kotlin, but not using passive views).

Passive Views

Passive Views (based on AutoInject ones) that enforces developer to create passive views, that are not aware of existence of Presenter. All communication from View to Presenter has to be done through providing Observables with given UI events. It's enforced by the fact that getPresenter() method of this kind of views does not return Presenter of some exact type, but as a general ViperPresenter, so calling any meaningful methods on it is impossible. As in the previous point, it also contains the pre baked classes for:

  • Butterknife - moviper-butterknife module (just like in sample-super-rx-ai-kotlin, but using passive views),
  • DataBinding - moviper-databinding module (check out sample-super-rx-databinding),
  • for Kotlin Android Extensions you shall use regular AiPassive Views from base module (check out sample-super-rx-ai-kotlin).

Choosing Presenter on runtime

A MoviperPresentersDispatcher tool allows you to choose the View's (especially Activity) presenter on the runtime without a need of putting it to the Bundle with all it's limitations or switching in . Sample launching of Activity with given presenter is available in sample-super-rx-ai, in ListingRouting#startUserDetailsActivity(...) here, and adjusting Activity to be started with any presenter that fits the View interface is showcased in UserDetailsActivity#createPresenter() here.

Attaching multiple presenters to the View

ViperPresentersList allows you to easily attach multiple presenters to the Passive Views. Sample usage is very simple and available in sample-super-rx-ai in UserDetailsActivity#createPresenter() here.

Service based VIPERs

Allow you to maintain a uniform architecture between your app's views and services. It includes support for:

  • regular Service's
  • IntentService's

Sample usage is showcased in sample-service

Independent VIPERS

need importing moviper-service module

Allow you to maintain a uniform architecture between your app's views and complex task objects that aren't strictly connected with any specific Android component.

Sample usage available in sample-independent-viper.

Test utils

Optional moviper-test module (see Dependency) contains useful testing tools:

  • FragmentTestRule to perform Fragment instrumentation tests in isolation,
  • MoviperActivityTestRule to perform Viper Activity instrumentation tests with proper cleanup,
  • ViewHolderTestRule to perform Recyclerview's ViewHolder instrumentation tests in isolation,
  • RxAndroidSchedulersOverrideRule to override AndroidSchedulers.mainThread() behaviour in unit tests,
  • ViewHolderUnitTestAcrivity to perform Recyclerview's ViewHolder Robolectric unit tests in isolation,
  • RecyclerViewMatcher to match RecyclerView's contents in Espresso instrumentation tests.

Check out the test modules of the samples to check out how easy is testing with Moviper and to see various usecases of moviper-test module.

Credits

This library is built on top of a great Mosby library by Hannes Dorfmann. Check out the project website.

I've also used a Lucas Urbas Interactor implementation idea presented in his Search viper architecture example.

I have followed Publish AAR to jCenter and Maven Central by Lopez Mikhael to publish Moviper to jCenter.

The great thanks for the my team that helped me in Moviper development implementing my ideas under my guidance:

License

Copyright 2017 Mateusz Koślacz

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You might also like...
A lightweight, good expandability Android library used for displaying different pages like loading, error, empty, timeout or even your custom page when you load a page
A lightweight, good expandability Android library used for displaying different pages like loading, error, empty, timeout or even your custom page when you load a page

中文 | English LoadSir 👉 👈 LoadSir是一个高效易用,低碳环保,扩展性良好的加载反馈页管理框架,在加载网络或其他数据时候,根据需求切换状态页面, 可添加自定义状态页面,如加载中,加载失败,无数据,网络超时,如占位图,登录失效等常用页面。可配合网络加载框架,结合返回 状态

Android part of the  Android Studio(IntellijIDEA) OkHttp Profiler plugin
Android part of the Android Studio(IntellijIDEA) OkHttp Profiler plugin

OkHttpProfiler Android Library Created by LocaleBro.com - Android Localization Platform The OkHttp Profiler plugin can show requests from the OkHttp l

Android common lib, include ImageCache, HttpCache, DropDownListView, DownloadManager, Utils and so on
Android common lib, include ImageCache, HttpCache, DropDownListView, DownloadManager, Utils and so on

android-common-lib 关于我,欢迎关注 微博:Trinea 主页:trinea.cn 邮箱:trinea.cn#gmail.com 微信:codek2 主要包括:缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、

dexposed enable 'god' mode for single android application.

What is it? Dexposed is a powerful yet non-invasive runtime AOP (Aspect-oriented Programming) framework for Android app development, based on the work

A Job Queue specifically written for Android to easily schedule jobs (tasks) that run in the background, improving UX and application stability.

This Project is Deprecated! Thanks to everybody who've used Android Priority JobQueue. It was designed in a world where there was no JobScheduler, RxJ

A plugin system that runs like a browser, but instead of load web pages, it load apk plugins which runs natively on Android system.
A plugin system that runs like a browser, but instead of load web pages, it load apk plugins which runs natively on Android system.

Android Dynamic Loader Android Dynamic Loader is a plugin system. The host application is like a browser, but instead of load web pages, it load plugi

LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.

#LiteOrm:Android高性能数据库框架 A fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line

🚀Plugin for Android Studio And IntelliJ Idea to generate Kotlin data class code from JSON text ( Json to Kotlin )
🚀Plugin for Android Studio And IntelliJ Idea to generate Kotlin data class code from JSON text ( Json to Kotlin )

JsonToKotlinClass Hi, Welcome! This is a plugin to generate Kotlin data class from JSON string, in another word, a plugin that converts JSON string to

Kick-starts Android application development.

Synopsis If you've made it here, chances are you are not quite as satisfied with the Android application framework as you could be. Same for us, that'

Comments
  • Detecting if presenter is attached on a BaseRxInteractor

    Detecting if presenter is attached on a BaseRxInteractor

    Hi, I think I can understand why a BaseRxInteractor needs no isPresenterAttached() logic as with BaseInteractor. However, in the case where one had a Presenter that had an addSubscription:

    public void attachView(ViewInterface view) {
            addSubscription(
                getInteractor().getData()
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(presenterData -> {
                            if (isViewAttached()) {
                                ViewModel vm = createViewModel(presenterData);
                                getView().updateViewModel(vm);
                            }
                        }, error -> {
                            if (isViewAttached()) {
                                ViewModel vm = createrViewModel(null);
                                getView().updateUserViewModel(vm);
                                didFailUserData(error.getLocalizedMessage());
                            }
                        })
            );
    }
    

    We have found that we required similar checks for subscriber.isDisposed() on any async work.

    For example:

    public Single<PresenterData>> getData() {
            return Single.create(subscriber -> {
                mService.getAPIData()
                        .subscribeOn(mJobScheduler)
                        // throttling logic and exponential retry logic goes here
                        .subscribe( 
                                response-> {
                                    // business logic here to parse data, filter, groom, etc 
                                    // PresenterData presenterData = doWork(response);
                                    if (!subscriber.isDisposed()) { //check if presenter is still attached
                                        subscriber.onSuccess(presenterData);
                                    }
                                }, throwable -> {
                                    if (!subscriber.isDisposed()) {
                                        subscriber.onError(throwable);
                                    }
                                }
                        );
            });
    }
    

    In light of this do you think the BaseRxInteractor should have some kind of isPresenterAttached() logic?

    opened by paulleo 4
  • Butterknife Unbind

    Butterknife Unbind

    After having read https://github.com/JakeWharton/butterknife/issues/585 and then looking at the module https://github.com/mkoslacz/Moviper/blob/master/moviper-butterknife/src/main/java/com/mateuszkoslacz/moviper/base/view/fragment/autoinject/butterknife/ViperButterKnifeFragment.java

    I have to ask : is the unbinding missing from ViperButterKnifeFragment? It looks like it.

    opened by abiemann 1
  • Fixes for Moviper tests

    Fixes for Moviper tests

    improv: reset presenter before every test & mock all observable used in attach fix: ClassCastException produced by @InjectMocks improv: start activity from routing tests

    opened by tomasznajda 1
  • Sample case when using a view you cannot extend (e.g. DialogFragment)

    Sample case when using a view you cannot extend (e.g. DialogFragment)

    What do you recommend doing when you cannot extend ViperFragment or ViperActivity? Let's say I have a custom view that already extends DialogFragment, what's the approach to rigging up / binding the presenter, interactor, router? I can't seem to find a suitable sample that fits this need.

    opened by elprl 2
Releases(v2.0.4)
  • v2.0.4(Jul 27, 2017)

  • v2.0.3(Jul 27, 2017)

    Enhancement

    • ViperAiViewHolder and ViperAiPassiveViewHolder:
      • bindViews() method added to ease recycling views management and separate view creation and view binding logic. Although it is not necessary to migrate to it from the regular injectViews it is strongly recommended for performance purposes.
    Source code(tar.gz)
    Source code(zip)
  • v2.0.2(Apr 6, 2017)

    Breaking change

    • From now IPC methods do not operate by default on a particular Scheduler. Please review your IPC streams, as in some cases this may be a breaking change.

    Enhancements

    • Inter-Presenter Communication (IPC):
      • from now IPC methods do not operate by default on a particular Scheduler (see above),
      • error handling adapted to RxJava 2.x,
      • introduced error handler that allows you subscribe to IPC errors. By default it prints an error using Log.e("Moviper, "IPC default error handler: ", e);,
      • added getPresenterInstanceOrError method that returns Single,
      • fixed some bugs.
    • Presenters (CommonBasePresenter):
      • fixed equality issues for presenters of different classes with the same name (regression introduced in 2.0.1)
    • ViperViewHolder:
      • fixed presenter detaching issue on scrolling the RecyclerView - presenters did not detach from a view on the recycle.
    • Bumped dependencies versions.
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Apr 6, 2017)

    Enhancement

    • From now presenters have random names at default, so you can create multiple presenters of a given class without overriding getName() with PresenterInstancesAccess enabled. It's useful when you don't want to use presenter instance access on the particular class but just regular PresentersAccessUtil.
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Mar 19, 2017)

  • v1.5.0(Mar 19, 2017)

    Breaking change & enhancement

    Library has ben split to multiple modules to avoid importing unnecessary dependencies to your project. See the Dependency paragraph of the readme to find out which ones you need.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0-alpha(Feb 9, 2017)

    Breaking changes:

    This release introduces some breaking changes. All stuff listed below is also mentioned in the Migration guide.

    • Unified methods for getting context in Routings.

    Enhancements

    Introduced:

    • AutoInject (Ai) Views that allow you to skip overriding the onCreate(...) / onViewCreated(..) method. Instead, in plain Ai Views you have to provide the layout id by overriding a getLayoutId() method and to perform any view injections, getting references to views etc. by overriding a injectViews() method. In addition, it contains the pre-baked classes, where these methods are already implemented inside of base classes for:
      • Butterknife,
      • DataBinding,
      • for Kotlin Android Extensions you have to use regular Ai Views.
    • Passive Views (based on AutoInject ones) that enforces developer to create passive views, that are not aware of existence of Presenter. All communication from View to Presenter has to be done through providing Observables with given UI events. It's enforced by the fact that getPresenter() method of this kind of views does not return Presenter of some exact type, but as a general ViperPresenter, so calling any meaningful methods on it is impossible. As in the previous point, it also contains the pre baked classes for:
      • Butterknife,
      • DataBinding,
      • for Kotlin Android Extensions you have to use regular AiPassive Views.
    • MoviperPresentersDispatcher tool that allows you to choose the View's (especially Activity) presenter on the runtime without a need of putting it to the Bundle with all it's limitations.
    • ViperPresentersList that allows you to easily attach multiple presenters to the Passive Views.
    • Service based VIPERs to allow you to maintain a uniform architecture between your app's views and services. It includes support for:
      • regular Service's
      • IntentService's
    • independent VIPERS to allow you to maintain a uniform architecture between your app's views and complex task objects that aren't strictly connected with any specific Android component.
    • a moviper-test module that contains useful testing tools:
      • FragmentTestRule to perform Fragment instrumentation tests in isolation,
      • MoviperActivityTestRule to perform Viper Activity instrumentation tests with proper cleanup,
      • ViewHolderTestRule to perform Recyclerview's ViewHolder instrumentation tests in isolation,
      • RxAndroidSchedulersOverrideRule to override AndroidSchedulers.mainThread() behaviour in unit tests,
      • ViewHolderUnitTestAcrivity to perform Recyclerview's ViewHolder Robolectric unit tests in isolation,
      • RecyclerViewMatcher to match RecyclerView's contents in Espresso instrumentation tests.

    And added some more Javadocs

    General

    • Introduced even more samples for new features:
      • sample-super-rx-ai-kotlin
      • sample-independent-viper
      • sample-ipc-ai
      • sample-rx-ai
      • sample-service
      • sample-super-rx-ai
      • sample-super-rx-ai-kotlin
      • sample-super-rx-databinding

    Internal

    • Increase tests coverage, also for non-TDD libs that we base onto.
    • Bumped dependencies versions:
      • RxJava to 1.2.6

    Credits

    Once again, many thanks to guys that helped me in Moviper development implementing my ideas under my guidance:

    • Tomasz Najda - extracting moviper-test module, implementing Viper services and independent Vipers and samples for the latter,
    • Bartosz Wilk - Moviper templates, some Ai Views, improving test coverage, implementing MoviperPresetnersDispatcher, super-rx-ai sample,
    • Jakub Jodelka - Viper service sample.
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0-alpha(Feb 5, 2017)

    Breaking changes

    This release introduces some breaking changes. All stuff listed below is also mentioned in the Migration guide.

    • Simplified Moviper internals to ease the troubleshooting and debugging.
    • Rename some methods to make them more self-explaining.
    • Removed Wipe (View-Interactor-Presenter-Entity) and Perv (Presenter-Entity-Routing-View) components as they did not add much value to the project but still needed the maintenance.
    • Removed deprecated methods.

    General

    • Introduced even more samples, now with VIPER testing showcases inside.

    Enhancements

    • Added support for ViewHolders. Now they can represent a View in a VIPER architecture. See sample-recyclerview.

    Internal

    • Routing activity attaching moved from constructor to the routing lifecycle.
    • Simplified a VIPER components lifecycle.
    • Simplified a presenter architecture.
    • Simplified a routing architecture.
    • Bumped dependencies versions:
      • RxJava to 1.2.3
      • buildtools to 25.0.2
      • support libs to 25.1.0

    Credits

    Many thanks to guys that helped me in Moviper development implementing my ideas.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0-alpha(Feb 5, 2017)

    General

    • Change the Moviper stage of development to alpha as some API methods may change.
    • Introduced completely new samples.

    Enhancements

    • Added the Rx flavored version of Moviper that lacks Presenter references in Interactor and Routing.
    • Added the Presenter args Bundle that allows passing arguments from Activity/Fragment extras to Routing and Interactor constructors.
    • Added the Moviper Inter-Presenter-Communication tool to avoid using a bus in the mentioned communication.

    Deprecated (will be removed in the next release)

    • Unnecessary Presenter isRoutingAttached() and isInteractorAttached() methods.

    Internal

    • Removed the unnecessary double-purging Interactor and Routing references in Presenter.
    • Fixed some improper @Nullable marks for Routing and Interactor in Presenter and ViewHelper/Context weak references in Routing, change them to @NonNull.
    • Bumped dependencies versions:
      • buildtools, appcompat and sdk to 25
      • gradle to 2.2.2
      • gradle-retrolambda to 3.3.1
      • RxJava to 1.2.2

    Credits

    • Great thanks to Jakub Jodełka (@jakubjodelka) for providing the brand new samples.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 5, 2017)

Owner
Mateusz Koślacz
Tech Lead in Movibe (https://movibe.it/)
Mateusz Koślacz
kotlin-core - A full framework for making Android apps. Based on Anko and Kotson.

kotlin-core This package is not Android-specific, and can be used across platforms. However, for a good example of use in Android, take a look at kotl

Lightning Kite 36 Oct 3, 2022
🔥 Android component-based routing framework

README-CN Latest version module krouter-core krouter-compiler krouter-annotation krouter-plugin version Features 支持通过路由获取intent 支持方法注解,通过路由调用方法 支持给fra

Jiaming Gu 6 Jun 24, 2022
A Model-View-Presenter / Model-View-Intent library for modern Android apps

Mosby A Model-View-Presenter and Model-View-Intent library for Android apps. Dependency dependencies { compile 'com.hannesdorfmann.mosby3:mvi:3.1.1

Hannes Dorfmann 5.5k Dec 25, 2022
Nucleus is an Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application.

Nucleus Deprecation notice Nucleus is not under develpment anymore. It turns out that Redux architecture scales way better than MVP/MVI/MVVM/MVxxx and

Konstantin Mikheev 2k Nov 18, 2022
Moxy is MVP library for Android

Moxy This Moxy repository is deprecated and no longer supported. Please migrate to the actual version of the Moxy framework at Moxy communuty repo. De

Arello Mobile 1.6k Dec 28, 2022
Minimal UI library for Android inspired by React

Anvil - reactive views for Android Anvil is a small Java library for creating reactive user interfaces. Originally inspired by React, it suits well as

null 1.4k Dec 23, 2022
a MVP library for Android favoring a stateful Presenter

DEPRECATED - no longer actively maintained ThirtyInch - a MVP library for Android This library adds Presenters to Activities and Fragments. It favors

HCI @ gcx 1k Dec 15, 2022
Android app built with MVP architectural approach and uses Marvel Comics API that allows developers everywhere to access information about Marvel's vast library of comics. :zap:

Villains & Heroes Android app built with MVP architectural approach and uses Marvel Comics API that allows developers everywhere to access information

André Mion 53 Jul 13, 2022
Crossword library for Android

Ararat Ararat is a crossword library for Android, written for and used by alphacross. It includes: Parsers for various formats CrosswordRenderer, whic

Akop Karapetyan 28 Oct 3, 2022
The most complete and powerful data-binding library and persistence infra for Kotlin 1.3, Android & Splitties Views DSL, JavaFX & TornadoFX, JSON, JDBC & SQLite, SharedPreferences.

Lychee (ex. reactive-properties) Lychee is a library to rule all the data. ToC Approach to declaring data Properties Other data-binding libraries Prop

Mike 112 Dec 9, 2022