Skip to content

Instantly share code, notes, and snippets.

@SergeyBurlaka
Created February 3, 2018 14:41
Show Gist options
  • Save SergeyBurlaka/4aec0ed81f410f607fd93e9d3beafe63 to your computer and use it in GitHub Desktop.
Save SergeyBurlaka/4aec0ed81f410f607fd93e9d3beafe63 to your computer and use it in GitHub Desktop.
public interface IToolbarEventListener {
void onNewTitle(String title);
void onNewSubtitle(String subtitle);
}
public interface IToolbarModelMutator {
void setTitle(String title);
void setSubtitle(String subtitle);
}
public interface IToolbarModelObserver {
String getTitle();
String getSubtitle();
void setListener(IToolbarEventListener listener);
}
public interface IViewModelComponent {
@NonNull
ToolbarModule toolbarViewModels();
@NonNull
LabelsModule labelsModule();
}
public class MainActivity {
...
//Здесь мы просто создаем фабрику для презентера, важно для понимания только то, что мы инжектим туда обзервер модели
@NonNull
@Override
protected ViperPresenter.Factory<IMainView, MainRouter, MainPresenter> provideFactory() {
return new MainPresenter.Factory(provideToolbarModelObserver());
}
@NonNull
@Override
public IToolbarModelMutator provideToolbarModelMutator() {
verifyComponentProvidersExist();
return ((RetainContainer<IViewModelComponent>) getSupportFragmentManager()
.findFragmentByTag(TAG_VIEW_MODEL_CONTAINER))
.provideComponent()
.toolbarViewModels()
.provideToolbarModelMutator();
}
@NonNull
@Override
public IToolbarModelObserver provideToolbarModelObserver() {
verifyComponentProvidersExist();
return ((RetainContainer<IViewModelComponent>) getSupportFragmentManager()
.findFragmentByTag(TAG_VIEW_MODEL_CONTAINER))
.provideComponent()
.toolbarViewModels()
.provideToolbarModelObserver();
}
private void verifyComponentProvidersExist() {
if(getSupportFragmentManager().findFragmentByTag(TAG_VIEW_MODEL_CONTAINER) == null) {
RetainContainer<IViewModelComponent> container = new RetainContainer<>();
IApplicationEnvironmentProvider applicationEnvironmentProvider = (IApplicationEnvironmentProvider) getApplication();
container.setFactory(new ViewModelComponentFactory(applicationEnvironmentProvider.provideContext()));
getSupportFragmentManager().beginTransaction()
.add(container, TAG_VIEW_MODEL_CONTAINER)
.commitNow();
}
}
...
}
public class MainPresenter extends ViperPresenter<IMainView, MainRouter> implements IToolbarEventListener {
@NonNull
private final IToolbarModelObserver toolbarModelObserver;
public MainPresenter(@NonNull IToolbarModelObserver toolbarModelObserver) {
this.toolbarModelObserver = toolbarModelObserver;
}
@Override
protected void onViewAttach() {
getView().setTitle(toolbarModelObserver.getTitle());
getView().setSubtitle(toolbarModelObserver.getSubtitle());
toolbarModelObserver.setListener(this);
}
@Override
protected void onViewDetach() {
toolbarModelObserver.setListener(null);
}
@Override
protected void onDestroy() {
}
@Override
public void onNewTitle(String title) {
getView().setTitle(title);
}
@Override
public void onNewSubtitle(String subtitle) {
getView().setSubtitle(subtitle);
}
...
public static final class Factory implements ViperPresenter.Factory<IMainView, MainRouter, MainPresenter> {
@NonNull
private final IToolbarModelObserver toolbarModelObserver;
public Factory(@NonNull IToolbarModelObserver toolbarModelObserver) {
this.toolbarModelObserver = toolbarModelObserver;
}
@Override
public MainPresenter create() {
return new MainPresenter(toolbarModelObserver);
}
}
}
public class PreferencesFragment {
//Здесь важно, что мы инжектим мутатор в презентер
@NonNull
@Override
protected ViperPresenter.Factory<IPreferencesView, MainRouter, PreferencesPresenter> provideFactory() {
ILabelsManagerProvider labelsManagerProvider = (ILabelsManagerProvider) getActivity();
IToolbarViewModelProvider toolbarViewModelProvider = (IToolbarViewModelProvider) getActivity();
return new PreferencesPresenter.Factory(
labelsManagerProvider.provideLabelsManager(),
toolbarViewModelProvider.provideToolbarModelMutator()
);
}
}
public class PreferencesPresenter extends ViperPresenter<IPreferencesView, MainRouter> {
@NonNull
private final ILabelsManager labelsManager;
@NonNull
private final IToolbarModelMutator toolbarModelMutator;
private PreferencesPresenter(@NonNull ILabelsManager labelsManager,
@NonNull IToolbarModelMutator toolbarModelMutator) {
this.labelsManager = labelsManager;
this.toolbarModelMutator = toolbarModelMutator;
}
@Override
protected void onViewAttach() {
toolbarModelMutator.setTitle(labelsManager.getPreferencesLabel());
toolbarModelMutator.setSubtitle("");
getView().setVersionCode(BuildConfig.VERSION_CODE);
getView().setVersionName(BuildConfig.VERSION_NAME);
}
@Override
protected void onViewDetach() {
}
@Override
protected void onDestroy() {
}
public static final class Factory implements ViperPresenter.Factory<IPreferencesView, MainRouter, PreferencesPresenter> {
@NonNull
private final ILabelsManager labelsManager;
@NonNull
private final IToolbarModelMutator toolbarModelMutator;
public Factory(@NonNull ILabelsManager labelsManager,
@NonNull IToolbarModelMutator toolbarModelMutator) {
this.labelsManager = labelsManager;
this.toolbarModelMutator = toolbarModelMutator;
}
@Override
public PreferencesPresenter create() {
return new PreferencesPresenter(labelsManager, toolbarModelMutator);
}
}
}
public class RetainContainer<Component> extends Fragment {
@NonNull
private final Object lock = new Object();
@Nullable
private volatile Component component;
private Factory<Component> factory;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@NonNull
public Component provideComponent() {
Component localInstance = component;
if(localInstance == null) {
synchronized (lock) {
localInstance = component;
if(localInstance == null) {
localInstance = component = factory.create();
}
}
}
return localInstance;
}
public void setFactory(Factory<Component> factory) {
this.factory = factory;
}
public interface Factory<T> {
T create();
}
}
public class ToolbarModel implements IToolbarModelObserver, IToolbarModelMutator {
private String title;
private String subtitle;
private IToolbarEventListener listener;
public ToolbarModel() {
}
@Override
public void setTitle(String title) {
this.title = title;
listener.onNewTitle(this.title);
}
@Override
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
listener.onNewSubtitle(this.subtitle);
}
@Override
public String getTitle() {
return this.title;
}
@Override
public String getSubtitle() {
return this.subtitle;
}
@Override
public void setListener(IToolbarEventListener listener) {
this.listener = listener;
}
}
public class ToolbarModule {
@NonNull
private final Object lock = new Object();
@Nullable
private volatile ToolbarModel model;
public ToolbarModule() {
}
@NonNull
public IToolbarModelMutator provideToolbarModelMutator() {
IToolbarModelMutator localInstance = model;
if(localInstance == null) {
synchronized (lock) {
localInstance = model;
if(localInstance == null) {
localInstance = model = new ToolbarModel();
}
}
}
return localInstance;
}
@NonNull
public IToolbarModelObserver provideToolbarModelObserver() {
IToolbarModelObserver localInstance = model;
if(localInstance == null) {
synchronized (lock) {
localInstance = model;
if(localInstance == null) {
localInstance = model = new ToolbarModel();
}
}
}
return localInstance;
}
}
public class ViewModelComponent implements IViewModelComponent {
@NonNull
private final ToolbarModule toolbar;
@NonNull
private final LabelsModule labelsModule;
public ViewModelComponent(Context context) {
this.toolbar = new ToolbarModule();
this.labelsModule = new LabelsModule(context.getResources());
}
@NonNull
@Override
public ToolbarModule toolbarViewModels() {
return toolbar;
}
@NonNull
@Override
public LabelsModule labelsModule() {
return labelsModule;
}
}
public class ViewModelComponentFactory implements RetainContainer.Factory<IViewModelComponent> {
@NonNull
private final Context context;
public ViewModelComponentFactory(@NonNull Context context) {
this.context = context;
}
@Override
public IViewModelComponent create() {
return new ViewModelComponent(context);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment