A small, yet full-featured framework that allows building View-based Android applications

Overview

Travis Build Android Arsenal Javadocs

Conductor

A small, yet full-featured framework that allows building View-based Android applications. Conductor provides a light-weight wrapper around standard Android Views that does just about everything you'd want:

Conductor
🎉 Easy integration
☝️ Single Activity apps without using Fragments
♻️ Simple but powerful lifecycle management
🚋 Navigation and backstack handling
🔀 Beautiful transitions between views
💾 State persistence
☎️ Callbacks for onActivityResult, onRequestPermissionsResult, etc
🏤 MVP / MVVM / MVI / VIPER / MVC ready

Conductor is architecture-agnostic and does not try to force any design decisions on the developer. We here at BlueLine Labs tend to use either MVP or MVVM, but it would work equally well with standard MVC or whatever else you want to throw at it.

Installation

implementation 'com.bluelinelabs:conductor:3.0.0'

// AndroidX Transition change handlers:
implementation 'com.bluelinelabs:conductor-androidx-transition:3.0.0'

// ViewPager PagerAdapter:
implementation 'com.bluelinelabs:conductor-viewpager:3.0.0'

// ViewPager2 Adapter:
implementation 'com.bluelinelabs:conductor-viewpager2:3.0.0'

// RxJava2 lifecycle support:
implementation 'com.bluelinelabs:conductor-rxlifecycle2:3.0.0'

// RxJava2 Autodispose support:
implementation 'com.bluelinelabs:conductor-autodispose:3.0.0'

// Lifecycle-aware Controllers (architecture components):
implementation 'com.bluelinelabs:conductor-archlifecycle:3.0.0'

SNAPSHOT

Just use 3.0.1-SNAPSHOT as your version number in any of the dependencies above and add the url to the snapshot repository:

allprojects {
  repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
  }
}

Components to Know

Conductor Components
Controller The Controller is the View wrapper that will give you all of your lifecycle management features. Think of it as a lighter-weight and more predictable Fragment alternative with an easier to manage lifecycle.
Router A Router implements navigation and backstack handling for Controllers. Router objects are attached to Activity/containing ViewGroup pairs. Routers do not directly render or push Views to the container ViewGroup, but instead defer this responsibility to the ControllerChangeHandler specified in a given transaction.
ControllerChangeHandler ControllerChangeHandlers are responsible for swapping the View for one Controller to the View of another. They can be useful for performing animations and transitions between Controllers. Several default ControllerChangeHandlers are included.
RouterTransaction Transactions are used to define data about adding Controllers. RouterTransactions are used to push a Controller to a Router with specified ControllerChangeHandlers, while ChildControllerTransactions are used to add child Controllers.

Getting Started

Minimal Activity implementation

public class MainActivity extends Activity {

    private Router router;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        ViewGroup container = (ViewGroup) findViewById(R.id.controller_container);

        router = Conductor.attachRouter(this, container, savedInstanceState);
        if (!router.hasRootController()) {
            router.setRoot(RouterTransaction.with(new HomeController()));
        }
    }

    @Override
    public void onBackPressed() {
        if (!router.handleBack()) {
            super.onBackPressed();
        }
    }

}

Minimal Controller implementation

public class HomeController extends Controller {

    @Override
    protected View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedViewState) {
        View view = inflater.inflate(R.layout.controller_home, container, false);
        ((TextView) view.findViewById(R.id.tv_title)).setText("Hello World");
        return view;
    }

}

Sample Project

Demo app - Shows how to use all basic and most advanced functions of Conductor.

Controller Lifecycle

The lifecycle of a Controller is significantly simpler to understand than that of a Fragment. A lifecycle diagram is shown below:

Controller Lifecycle

Advanced Topics

Retain View Modes

setRetainViewMode can be called on a Controller with one of two values: RELEASE_DETACH, which will release the Controller's view as soon as it is detached from the screen (saves memory), or RETAIN_DETACH, which will ensure that a Controller holds on to its view, even if it's not currently shown on the screen (good for views that are expensive to re-create).

Custom Change Handlers

ControllerChangeHandler can be subclassed in order to perform different functions when changing between two Controllers. Two convenience ControllerChangeHandler subclasses are included to cover most basic needs: AnimatorChangeHandler, which will use an Animator object to transition between two views, and TransitionChangeHandler, which will use Lollipop's Transition framework for transitioning between views.

Child Routers & Controllers

getChildRouter can be called on a Controller in order to get a nested Router into which child Controllers can be pushed. This enables creating advanced layouts, such as Master/Detail.

RxJava Lifecycle

If the AutoDispose dependency has been added, there is a ControllerScopeProvider available that can be used along with the standard AutoDispose library.

Community Projects

The community has provided several helpful modules to make developing apps with Conductor even easier. Here's a collection of helpful libraries:

License

Copyright 2020 BlueLine Labs, Inc.

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.
Comments
  • Dialogs with Conductor

    Dialogs with Conductor

    What is the recommended way to use dialogs (alias AlertDialogs)? Can I somehow treat them as controllers?

    With regular fragments I am mostly wrapping Dialogs in a DialogFragment so they survive runtime changes.

    opened by PaulWoitaschek 38
  • [Feature] Nested backstacks

    [Feature] Nested backstacks

    Hi!

    Is there any way to push a [child] controller from within another child controller?

    Let's say I'm displaying a child controller (named A) in a container view (named V), that it is just a part of the whole screen.

    What I want is to push another controller from A and make its view be contained in V.

    From what I understand, if we push a controller using the router, that would replace the view of the parent controller, and that's not what I want to achieve.

    Thank you in advance!

    EDIT

    My use case is:

    • I want a tabbed controller so I'm using ControllerPagerAdapter.
    • I want its child controllers to have their own backstacks so I can navigate within that "section" and keep the tabbar always visible.
    opened by mheras 29
  • Thoughts on Conductor and the new Android architecture components

    Thoughts on Conductor and the new Android architecture components

    Hi,

    Wondering what your thoughts are on the introduction of the new architecture components introduced by Google at I/O and how they would/could interact with Conductor? Especially the LifeCycle and ViewModel approaches.

    I don't view them as being orthogonal to the Conductor offerings, but it would be interesting to have your take on how it would make sense to use them with conductor (if at all).

    opened by Wrywulf 25
  • Add an onCreate() method

    Add an onCreate() method

    Currently developers are expected to do controller initialization in the constructor, which is great for some stuff, but makes other things a lot harder. Controllers don't have a reference to a router, activity, or parent controllers in the constructor, so things like dagger injection become more tricky. If you require references to these things for your initialization, you have to wait for the onCreateView() callback, then make sure you only run that code block once. Awkward.

    An onCreate() method would be the callback signaling that the controller is fully configured (minus the view) and has all the references it'll need.

    opened by EricKuck 20
  • Adds ViewModel support to the Arch. Comp. library

    Adds ViewModel support to the Arch. Comp. library

    • A ViewModelController that has its own ViewModelStore
    • The ViewModelController extends LifecycleController so can be used to subscribe to LiveData
    • Also provides a ViewModelProvider factory method
    • The Architecture Components library version is updated to 1.1.0
    • Includes demo usage in ViewModelDemoController

    Based on the discussion in https://github.com/bluelinelabs/Conductor/issues/395

    This solution is also available as standalone library: https://github.com/miquelbeltran/conductor-viewmodel/tree/master which also fixes the Lifecycle events to handle the LiveData observer subscription properly.

    Currently this PR depends on https://github.com/bluelinelabs/Conductor/pull/383 as well, because the current implementation of the LifecycleController can't be used to observe LiveData as the LiveData observer is not being removed in onDestroyView.

    opened by miquelbeltran 18
  • Multiple Controllers getting Attached On Orientation Change

    Multiple Controllers getting Attached On Orientation Change

    I probably just messed something up in my migration to v2, but this is the behavior I'm noticing:

    With Controller A on screen, turn the screen off and then back on.

    Navigate to Controller B. Change orientation of the device.

    After the orientation change, views for both A and B were attached to the screen. This can be repeated, adding another controller with each cycle.

    I've been having trouble figuring out what's going on here. - specifically what's triggering the controller which was on screen during the screen on/off to be reattached on the orientation change. Not sure if it's a problem with the library or my implementation. Any thoughts?

    opened by mmangliers 18
  • Transition between two Controllers with RecyclerViews not working

    Transition between two Controllers with RecyclerViews not working

    My setup:

    Controller A (movie list):

    • RecyclerView with ImageViewHolder

    Controller B (movie detail):

    • RecyclerView with HeaderImageViewHolder

    Problem: I want to add a transition from Controller A to Controller B with the standard ArcFadeMoveChangeHandler to have a beautiful animation between these two controllers. I added unique transitionNames to the movie items and forward the clicked item transitionName to Controller B. In the onBindView of the adapter of Controller B this transitionName is set to the HeaderImageViewHolder, but the transition is not working. I think it is because the transition is started before recyclerview is ready

    Question: I searched and found that it is possible to postpone the enter transition, but this is not working. how can i get this transtion from one item in a recyclerview to an item in another controllers recyclerview to work correctly?

    opened by Bodo1981 17
  • lifecycle

    lifecycle

    When pushing second controller, i have lifecycle: Controller2 - onViewBound Controller2 - onAttach Controller1 - onDetach Controller1 - onDestroyView it's wrong and i have problems when unsubscribe/unregister listeners/broadcasts/subscriptions

    opened by gerc99 17
  • [QUESTION] Best practices for MVP with plain Conductor

    [QUESTION] Best practices for MVP with plain Conductor

    On your homepage you say: "We here at BlueLine Labs tend to use either MVP or MVVM".

    I want to use MVP with conductor but without mosby and I'm aware of the following stuff:

    As I'm pretty new to Android development and completely new to conductor, I still have open questions and I would like to hear how you at BlueLine Labs use MVP with conductor.

    Questions:

    • When do you create the presenter in the controller?
      • onAttach() / onDetach()
        • Does not make sense to me as the lifecycle is probably too short then
      • postCreateView() / preDestroyView() --> like mosby-conductor
        • Controllers with RETAIN_RELEASE would then create various presenter instances, right?
        • I'm not sure about this. I guess there is a reason why some controllers retain their view. Wouldn't it then be usefull to retain the presenter instance as well?
      • Constructor(s) / onDestroy()
        • I've never seen this but probably it would have done it like that.
        • What are the downsides I don't see?
    • How do you create the presenter in the controller?
      • by calling its constructor
      • by a presenter factory
      • by injection via e.g. dagger 2
    • How do you deal with state in the presenter?
      • Views can have state (onSaveViewState()/onRestoreViewState())
      • Controllers can have state (onSaveInstanceState()/onRestoreInstanceState())
      • Presenters most probably will have their independent state as well, right?
      • How and when should the presenter's state be saved/restored?
        • never: e.g. because this is done in the controller which calls the presenter's constructor with all parameters necessary to restore the presenter's "state" (not sure if this would be feasible)
        • calling appropriate presenter methods in onSaveViewState()/onRestoreViewState()
          • should the presenter save it's state in the same bundle?
        • calling appropriate presenter methods in onSaveInstanceState()/onRestoreInstanceState()
          • should the presenter save it's state in the same bundle?
    • Would it be possible to see the interfaces and base classes you use at BlueLine Labs for MVP?
      • Maybe just a stripped down version to get the idea.

    Thank you in advance.

    opened by StephanSchuster 15
  • [QUESTION] What is the idea of having a tag for child routers?

    [QUESTION] What is the idea of having a tag for child routers?

    I couln't find any example usage of tags for child routers. That's why I'm asking. Looking at the sources it seems that it is possible to have multiple routers with different tags for the same container. Right? Then, when I push a controller to each of them, the according views are all attached to the same container via change handler. Right? The order (z-index) in which the children are displayed in the container (e.g. FrameLayout) depends on the push order because change handler just use container.addView(). Right? Due to this it seems difficult to control which view is currently shown (on top). Maybe it makes more sense if the views of the different controllers/routers are not shown on top of each other but besides each other (e.g. with RelativeLayout or ConstraintLayout and according layout properties set for the views). But wouldn't it be clearer to use different containers when showing views side by side. I'm confused.

    I'm sure tags for child routers have a reason and I'm just too stupid to see it. Or have I misunderstood something?

    Any hints are appreciated.

    opened by StephanSchuster 15
  • StackOverflowError: ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241)

    StackOverflowError: ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241)

    Fatal Exception: java.lang.StackOverflowError: stack size 8MB at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.ControllerHostedRouter.getTransactionIndexer(ControllerHostedRouter.java:241) at com.bluelinelabs.conductor.Router.getActivity(Router.java:801) at com.bluelinelabs.conductor.Router.getActivity(Router.java:792) at com.bluelinelabs.conductor.Router.popController(Router.java:137) at com.bluelinelabs.conductor.Router.popCurrentController(Router.java:119) at com.bluelinelabs.conductor.Router.handleBack(Router.java:97) at classifieds.yalla.shared.navigation.TabMenuNavigator.handleBack(TabMenuNavigator.kt:194) at classifieds.yalla.features.main.TabMenuController.onBackPressed(TabMenuController.kt:159) at classifieds.yalla.shared.activity.ConductorBaseActivity.onBackPressed(ConductorBaseActivity.kt:84) at android.app.Activity.onKeyUp(Activity.java:2807) at android.view.KeyEvent.dispatch(KeyEvent.java:2717) at android.app.Activity.dispatchKeyEvent(Activity.java:3115) at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:534) at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:58) at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:316) at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:323) at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4390) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4361) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3905) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3958) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3924) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4051) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3932) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4108) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3905) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3958) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3924) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3932) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3905) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3958) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3924) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4084) at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4252) at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2437) at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2001) at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1992) at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2414) at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) at android.os.MessageQueue.nativePollOnce(MessageQueue.java) at android.os.MessageQueue.next(MessageQueue.java:323) at android.os.Looper.loop(Looper.java:142) at android.app.ActivityThread.main(ActivityThread.java:6379) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

    opened by MkhytarMkhoian 14
  • Fix Demo Shared Element can't back press problem

    Fix Demo Shared Element can't back press problem

    Cloned the code and run the demo app. Found that if user get into Shared Element Demos and click a photo, they can't go back. Because the transitionName is wrong.

    opened by harrygaoos 0
  • Android 14 a partly 13 will break back navigation !

    Android 14 a partly 13 will break back navigation !

    We need to start working on the new behavior, otherwise whole library will be broken on those targeting 13 and for all on 14+

    Activity.onBackPressed won't be called anymore. Library will need to tell framework ahead of time if it will take 'back' over

    https://developer.android.com/about/versions/13/features/predictive-back-gesture#migrate-androidx

    opened by ursusursus 1
  • Compiled conductor lint classes have different class version

    Compiled conductor lint classes have different class version

    We are having this error when trying to build our project: java.lang.UnsupportedClassVersionError: com/bluelinelabs/conductor/lint/ControllerIssueDetector has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

    Having looked at the aar archive here I found that IssueRegistry has class file version 52, and ControllerIssueDetector has 55.

    Is there any reason for them to have different versions? This probably won't fix our issue but I'm still curious.

    opened by mpetrychko 0
  • Controller.requestPermission crashes on android pre 6

    Controller.requestPermission crashes on android pre 6

    LifecycleHandler extends android.app.Fragment

    this then obviously causes a crash on android 5, and is very unexpected

    There is no way to workaround it as its deep within Conductor internals

    extending support Fragment would fix it

    opened by ursusursus 0
  • Fixes issues in Router.pushController, Router.popController & Router.setBackstack where pushChangeHandler().removesFromViewOnPush() was not respected

    Fixes issues in Router.pushController, Router.popController & Router.setBackstack where pushChangeHandler().removesFromViewOnPush() was not respected

    Motivation: I encountered these issues while migrating existing code to androidX Navigation, and thus creating a ControllerNavigator along with others to support coexisting FragmentDialogs/Controllers with the hope of being able to just plug in Fragments (if the need ever arises) or hopefully Compose when its more mature and time permits.

    Issue: During this pursuit, I started leveraging Router.setBackstack for all changes to the Router.backstack, and in my test app I had a flow that looked like this: AboutController -> DialogController (with pushChangeHandler().removesFromViewOnPush() = false) -> DetailsController

    When pressing back while on DetailsController, the DialogController would re-appear, but without AboutController being visible underneath. During debugging I found that AboutController was not properly detached, even though its view was removed during the transition from DialogController -> DetailsController.

    Another issue that would manifest is if we take the following backstack: AboutController -> DialogController (with pushChangeHandler().removesFromViewOnPush() = false) -> DetailsAController -> DetailsBController When pressing back while on DetailsBController, the transitions would not be as expected, since it would first transition from(DetailsBController) to(null), and then from(null) to(DetailsAController), rather than the expected from(DetailsBController) to(DetailsAController).

    While I suppose not popping a dialog when navigating away from it, is atypical behaviour, I see no reason why it shouldn't be supported. A concrete use case in the app I'm working on is showing a dialog to select Time and then the option to open another dialog to select Date.

    The Fix: I added three test cases to RouterTests which proved the issue prior to my fix, during which I discovered that pushController shared the same issue as setBackstack, and that popController would not properly attach all views. I also updated the demo app to have let the DialogController navigate to another Controller, to trigger some of this behaviour and verify transitions looked as expected. I realise that this code may not be something you'd want in the repo, but I thought I'd leave it in a separate commit, for your testing convenience - and for ease of removal if need be.

    Inspired by how replaceTopController worked, I used that, along with ensuring that getVisibleTransactions would no longer incorrectly assume that any transaction prior to a removesFromViewOnPush=false transaction, is visible.

    Perhaps there are other cases which I didn't think to trigger, so hopefully whoever reviews this has more intimate knowledge of the inner Router workings, and can have a think as to whether there are other cases, or whether it would be better to change performControllerChange to handle some of these fixes too. The issues seem related to #608, since both are about removesFromViewOnPush when manipulating the backstack, but I also noticed that ViewLeakTests.testViewRemovedIfLayeredNotRemovesFromViewOnPush was making the assumption that the Controller which comes before the one with removesFromViewOnPush=false remains attached even when pushing a new Controller with removesFromViewOnPush=true on top - which to me was the whole issue.

    Thanks for many years of Conductor-awesomeness, I've truly been happy using it, just as I am happy to be able to contribute meaningfully (as you hopefully agree with! :) ) /Christian

    Some brief video recordings of two issues before and after my fix:

    https://user-images.githubusercontent.com/62065253/153869081-c0481500-b986-4305-8a13-aa187c8b0c5a.mp4

    https://user-images.githubusercontent.com/62065253/153869095-e52bf9ca-0990-4f24-a548-194a98fc332c.mp4

    https://user-images.githubusercontent.com/62065253/153869101-cd7aa9de-7b69-4b25-bcad-5cb928fe36f8.mp4

    https://user-images.githubusercontent.com/62065253/153869099-3642f40b-153b-47cf-9b11-e4bab9032202.mp4

    opened by chc-unwire 3
Releases(3.1.9)
  • 2.1.5(Aug 2, 2018)

    • Lots and lots of bug fixes
    • First official release with support for architecture components's lifecycle
    • Added SharedElementTransitionChangeHandler, which handles transitions much more robustly
    • Removed all synthetic accessors, lowering overall method count
    Source code(tar.gz)
    Source code(zip)
  • 2.1.4(Jul 5, 2017)

    • Added onContextAvailable and onContextUnavailable callback to controllers (helpful for dependency injection)

    • Added modules for Autodispose and Architecture Components's Lifecycle

    • Fixes issue where calling setBackstack repeatedly could result in a situation where multiple ControllerChangeHandlers are executing at the same time and interfering with each others states (#263)

    • Fixes a case that caused the incorrect change handler to execute when setting the backstack (fixes #286)

    • Now ensures that parent controller is restored after process death (fixes #300)

    • Fixes issue when immediately creating two routers in the same Activity (fixes #299)

    • Fixes attach state management when a controller is pushed while the Activity is paused. (Fixes #303)

    • shouldShowRequestPermissionRationale now returns the correct result. Fixes #317

    • Args are now restored to a controller after process death even if there is only a no-arg constructor. Fixes #313

    Source code(tar.gz)
    Source code(zip)
  • 2.1.3(May 3, 2017)

    • Fixes views never attaching if the host activity is stopped before inflation (#273)
    • Now properly handles pushing and popping controllers immediately back-to-back (#274)
    • Fixes horizontal change handlers in ViewPagers (#279)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.2(Apr 5, 2017)

    • Fixed issue where child controllers added while the parent is in the process of transitioning off the screen would not be properly restored (#256)
    • Now ensures view hierarchy-affecting calls are made on the main thread. (#255)
    • Args and savedInstanceState bundles now have classLoaders properly set. (#246)
    • Now passes along the correct view state for RestoreViewOnCreateController (#258)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.1(Mar 3, 2017)

    • Added missing nullity annotations for pager adapters (#219)
    • Routers now properly remove views of all owned controllers on destroy (#221)
    • TransitionChangeHandler is now much more flexible (doesn’t force you to add/remove views)
    • Added startIntentSenderForResult method to controller (#235)
    • Added ability to specify the maximum number of pages for which states should be saved (#236)
    • Fixes popToTransaction calls when removesViewOnPush is set to false in a change handler (#239)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Feb 2, 2017)

    • Added documentation for cases where @Nullable methods can return null (#218)
    • Now ensures getActivity() will not return null in preDestroyView for child Controllers (#208)
    • Fixed incorrect alpha values when FadeChangeHandler was prematurely aborted (#205)
    • Now correctly calls onDetach when the host Activity is stopped, even if the view was not detached from the window (#213)
    • Revamped how child backstacks are handled to be more reliable with unforseen uses of state restoration (#194, #217)
    • Deprecated ControllerPagerAdapter in favor of using RouterPagerAdapter everywhere, as it is more robust and has feature parity.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.7(Jan 19, 2017)

    • Fixes a memory leak introduced in 2.0.6
    • setRoot now passes the from view to the change handler correctly
    • Fixed issues with aborted AnimationChangeHandlers leaving view artifacts in the hierarchy
    • Fixed controllers deep in the backstack potentially not having a reference to their hosting Router when added via setBackstack
    Source code(tar.gz)
    Source code(zip)
  • 2.0.6(Jan 18, 2017)

    • Lint checks should run much faster now (#184)
    • Now internally ensures change handlers are not reused (#179)
    • Ensures onSaveViewState is called for an edge case (#185)
    • Now throws an exception when pushing destroyed controllers
    • Fixed child controllers being removed before the parent is animated out (#199)
    • Now ensures the entire view hierarchy is attached before calling onAttach (#201)
    • Now ensures the view state Bundle has a valid ClassLoader before use (#198)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.5(Dec 14, 2016)

    • Added support for RxLifecycle2 (RxJava 2)
    • Added a RouterPagerAdapter to conductor-support. This should be used over a ControllerPagerAdapter when individual pages might have their own backstacks and navigation).
    • Lots of bug fixes (#165, #166, #172)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.4(Dec 14, 2016)

  • 2.0.3(Oct 3, 2016)

    • Lots of bug fixes (#116, #124, #127) . Updating soon is recommended.
    • Also brings updated RxJava and RxLifecycle dependencies if using that additional dependency.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Jul 12, 2016)

  • 2.0.0(Jun 27, 2016)

    • All controllers can now have child routers
    • Backstacks can now be synthesized for better deep linking
    • Lots of little bug fixes and improvements
    Source code(tar.gz)
    Source code(zip)
  • 1.1.6(May 12, 2016)

  • 1.1.5(May 11, 2016)

  • 1.1.4(Apr 16, 2016)

    • Router, Activity, target controller, etc is all available in onRestoreInstanceState() now
    • Added lifecycle listener methods for onSaveViewState() and onRestoreViewState()
    Source code(tar.gz)
    Source code(zip)
  • 1.1.3(Apr 12, 2016)

    Host activities can now call the router's onActivityResult method to propagate the call to controllers that have registered for it with registerForActivityResult.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Apr 5, 2016)

    Controllers can now opt to receive onCreateOptionsMenu(Menu, MenuInflater), onPrepareOptionsMenu(Menu), and onOptionsItemSelected(MenuItem) callbacks by registering with the setHasOptionsMenu(boolean) method.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Apr 4, 2016)

    I know, I know, breaking changes do not belong in a minor release. This project was not ready for a v2 yet though, so we opted to break that rule. Sorry everyone!

    Breaking Lifecycle Updates

    • onSaveViewState() and onRestoreViewState() are now called symmetrically and live outside of onAttach() and onDetach(), as per #6
    • inflateView() and onBindView() have been merged into onCreateView(), as per #8
    • onUnbindView() has been renamed to onDestroyView() to match the new onCreateView() method

    Other Changes

    • setTargetController() is no longer final. It can now be overridden in order to allow controllers to block others from setting their target, in an effort to address #5 without creating too many confusing constructor options.
    Source code(tar.gz)
    Source code(zip)
Owner
BlueLine Labs
A premier mobile app and web development company based out of Chicago, IL.
BlueLine Labs
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
A modern framework for full stack web apps in Kotlin

Kobweb is an opinionated Kotlin framework for creating websites and web apps, built on top of Web Compose and inspired by Next.js and Chakra UI.

Varabyte 425 Jan 8, 2023
Cross-platform framework for building truly native mobile apps with Java or Kotlin. Write Once Run Anywhere support for iOS, Android, Desktop & Web.

Codename One - Cross Platform Native Apps with Java or Kotlin Codename One is a mobile first cross platform environment for Java and Kotlin developers

Codename One 1.4k Dec 23, 2022
Rosie is an Android framework to create applications following the principles of Clean Architecture.

Rosie The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times. — Robert C. Martin in Clean Cod

Karumi 1.8k Dec 28, 2022
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

马天宇 1.5k Nov 19, 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
Source++ is an open-source live coding platform. Add breakpoints, logs, metrics, and tracing to live production applications

Source++ is an open-source live coding platform. Add breakpoints, logs, metrics, and distributed tracing to live production software in real-time on-d

Source++ 40 Dec 14, 2022
Small Warp Plugin developed in Kotlin

Warps A small warps plugin for the 1.17 SMP. Minecraft 1.17 Spigot Contributing Install Java 16 Fork this repo Clone your fork Make your changes Use h

MenuDocs 6 Feb 19, 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
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
A data-binding Presentation Model(MVVM) framework for the Android platform.

PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED. As personal time contraints, I am currently unable to keep up. Please use official android da

RoboBinding open source 1.3k Dec 9, 2022
Android Plugin Framework

Android Plugin Framework This project is pre-mature and may be changed very frequently. Introduction Android Plugin Framework (APF) aims to providing

Umeng Limited 322 Nov 17, 2022
MVVM framework for Android

RoboMVVM - MVVM Framework For Android RoboMVVM is an open source library that facilitates the use of the MVVM pattern in Android apps. The MVVM patter

Debdatta Basu 55 Nov 24, 2020
VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS team, which is intended to speed up the first screen of websites working on Android and iOS platform.

VasSonic: A Lightweight And High-performance Hybrid Framework VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS

Tencent 11.6k Dec 30, 2022
🔪 AOP development framework implemented through *Annotation + ASM + Gradle Transform API* for Android🤖

?? AOP development framework implemented through *Annotation + ASM + Gradle Transform API* for Android??

Pumpkin 325 Nov 22, 2022
UltimateAndroid is a rapid development framework for developing your apps

UltimateAndroid Version:0.10.2 UltimateAndroid is a rapid development framework for developing apps Master branch: Dev branch: V0.7.0 Ui Demo screensh

MarshalChen 2.1k Dec 26, 2022
A framework for hook java methods.

Legend Projects are out of date, plese move to: Whale Hook What is Legend? Legend is a Hook framework for Android Development, it allows you to Hook J

Lody 1.6k Dec 15, 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
A Mosby based VIPER library for Android

Moviper A Mosby based VIPER library for Android Why Moviper? You got tired because of fact that your Activities and Fragments were becoming god classe

Mateusz Koślacz 78 Nov 29, 2022