From 7aa9aa9769ff896d70a18a845a1e0520799d048e Mon Sep 17 00:00:00 2001 From: sockeqwe Date: Tue, 24 Apr 2018 13:29:50 +0200 Subject: [PATCH] Added MVI Dialog Fragment --- .../mosby3/mvi/MviDialogFragment.java | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 mvi/src/main/java/com/hannesdorfmann/mosby3/mvi/MviDialogFragment.java diff --git a/mvi/src/main/java/com/hannesdorfmann/mosby3/mvi/MviDialogFragment.java b/mvi/src/main/java/com/hannesdorfmann/mosby3/mvi/MviDialogFragment.java new file mode 100644 index 00000000..de7d5d6c --- /dev/null +++ b/mvi/src/main/java/com/hannesdorfmann/mosby3/mvi/MviDialogFragment.java @@ -0,0 +1,186 @@ +/* + * Copyright 2016 Hannes Dorfmann. + * + * 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. + * + */ + +package com.hannesdorfmann.mosby3.mvi; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Bundle; +import android.support.annotation.CallSuper; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.hannesdorfmann.mosby3.FragmentMviDelegate; +import com.hannesdorfmann.mosby3.FragmentMviDelegateImpl; +import com.hannesdorfmann.mosby3.MviDelegateCallback; +import com.hannesdorfmann.mosby3.mvp.MvpPresenter; +import com.hannesdorfmann.mosby3.mvp.MvpView; + +/** + *

+ * This abstract class can be used to extend from to implement an Model-View-Intent pattern with + * this dialog fragment as View and a {@link MviPresenter} to coordinate the View and the underlying + * model (business logic) + *

+ * + *

+ * Per default {@link FragmentMviDelegateImpl} is used with the following lifecycle: + * The View is attached to the Presenter in {@link Fragment#onViewCreated(View, Bundle)}. + * So you better instantiate all your UI widgets before that lifecycle callback (typically in + * {@link + * Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle)}. The View is detached from Presenter in + * {@link Fragment#onDestroyView()} + *

+ * + * @author Hannes Dorfmann + * @since 3.0.0 + */ +public abstract class MviDialogFragment> extends Fragment + implements MvpView, MviDelegateCallback { + + private boolean isRestoringViewState = false; + protected FragmentMviDelegate mvpDelegate; + + @CallSuper @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getMvpDelegate().onCreate(savedInstanceState); + } + + @CallSuper @Override public void onDestroy() { + super.onDestroy(); + getMvpDelegate().onDestroy(); + } + + @CallSuper @Override public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + getMvpDelegate().onSaveInstanceState(outState); + } + + @CallSuper @Override public void onPause() { + super.onPause(); + getMvpDelegate().onPause(); + } + + @CallSuper @Override public void onResume() { + super.onResume(); + getMvpDelegate().onResume(); + } + + @CallSuper @Override public void onStart() { + super.onStart(); + getMvpDelegate().onStart(); + } + + @CallSuper @Override public void onStop() { + super.onStop(); + getMvpDelegate().onStop(); + } + + @CallSuper @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getMvpDelegate().onViewCreated(view, savedInstanceState); + } + + @CallSuper @Override public void onDestroyView() { + super.onDestroyView(); + getMvpDelegate().onDestroyView(); + } + + @CallSuper @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + getMvpDelegate().onActivityCreated(savedInstanceState); + } + + @CallSuper @Override public void onAttach(Activity activity) { + super.onAttach(activity); + getMvpDelegate().onAttach(activity); + } + + @Override public void onAttach(Context context) { + super.onAttach(context); + getMvpDelegate().onAttach(context); + } + + @CallSuper @Override public void onDetach() { + super.onDetach(); + getMvpDelegate().onDetach(); + } + + @CallSuper @Override public void onAttachFragment(Fragment childFragment) { + super.onAttachFragment(childFragment); + getMvpDelegate().onAttachFragment(childFragment); + } + + @CallSuper @Override public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getMvpDelegate().onConfigurationChanged(newConfig); + } + + /** + * Instantiate a presenter instance + * + * @return The {@link MvpPresenter} for this viewState + */ + @NonNull public abstract P createPresenter(); + + /** + * Get the mvp delegate. This is internally used for creating presenter, attaching and detaching + * viewState from presenter. + * + *

Please note that only one instance of mvp delegate should be used per Fragment + * instance. + *

+ * + *

+ * Only override this method if you really know what you are doing. + *

+ * + * @return {@link FragmentMviDelegate} + */ + @NonNull public FragmentMviDelegate getMvpDelegate() { + if (mvpDelegate == null) { + mvpDelegate = new FragmentMviDelegateImpl(this, this); + } + + return mvpDelegate; + } + + @NonNull @Override public V getMvpView() { + try { + return (V) this; + } catch (ClassCastException e) { + String msg = + "Couldn't cast the View to the corresponding View interface. Most likely you forgot to add \"Fragment implements YourMvpViewInterface\".\""; + Log.e(this.toString(), msg); + throw new RuntimeException(msg, e); + } + } + + @Override public void setRestoringViewState(boolean restoringViewState) { + this.isRestoringViewState = restoringViewState; + } + + protected boolean isRestoringViewState() { + return isRestoringViewState; + } +}