-
-
Save ntoskrnl/44f6a26ded95665544501e888cb0b00e to your computer and use it in GitHub Desktop.
Android. Example of how to store presenter in retained fragment and enable it to persist and restore view state.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Presenter<in V, in R> { | |
fun create() | |
fun attachRouter(router: R) | |
fun attachView(view: V) | |
fun detachView() | |
fun detachRouter() | |
fun destroy() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.os.Bundle | |
interface PresenterProvider { | |
fun providePresenter(key: String, savedState: Bundle?): Presenter<*, *> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context | |
import android.os.Bundle | |
import android.support.v4.app.Fragment | |
class PresenterRetainedFragment() : Fragment() { | |
private var presenterProvider: PresenterProvider? = null | |
private val presenters = mutableMapOf<String, Presenter<*, *>>() | |
override fun onAttach(context: Context?) { | |
super.onAttach(context) | |
presenterProvider = context as? PresenterProvider | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
retainInstance = true | |
if (savedInstanceState != null) { | |
savedInstanceState.getStringArray("keys") | |
.filter { it !in presenters.keys } | |
.map { key -> | |
key to presenterProvider?.providePresenter(key, savedInstanceState.getBundle("$key.state")) | |
} | |
.forEach { | |
val (key, presenter) = it | |
if (presenter != null) { | |
presenters.put(key, presenter) | |
presenter.create() | |
} | |
} | |
} | |
} | |
override fun onSaveInstanceState(outState: Bundle?) { | |
super.onSaveInstanceState(outState) | |
outState?.putStringArray("keys", presenters.keys.toTypedArray()) | |
presenters.entries.forEach { entry -> | |
val (key, presenter) = entry | |
val state = Bundle() | |
(presenter as? StatefulPresenter)?.saveState(state) | |
outState?.putBundle("$key.state", state) | |
} | |
} | |
override fun onDestroy() { | |
if (isRemoving) { | |
presenters.values.forEach { it.destroy() } | |
presenters.clear() | |
} | |
super.onDestroy() | |
} | |
fun addPresenter(key: String, presenter: Presenter<*, *>) { | |
presenters[key] = presenter | |
} | |
fun getPresenter(key: String): Presenter<*, *>? { | |
return presenters[key] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.support.v4.app.Fragment | |
import android.support.v4.app.FragmentActivity | |
import android.support.v4.app.FragmentManager | |
fun <P : Presenter<V, R>, V, R> FragmentManager.getOrCreatePresenter(key: String, provider: PresenterProvider): P { | |
var container = findFragmentByTag("presenters") as PresenterRetainedFragment? | |
if (container == null) { | |
container = PresenterRetainedFragment() | |
beginTransaction() | |
.add(container, "presenters") | |
.commitNow() | |
} | |
val foundPresenter = container.getPresenter(key) | |
return when (foundPresenter) { | |
null -> { | |
val newPresenter = provider.providePresenter(key, null) | |
container.addPresenter(key, newPresenter) | |
newPresenter.create() | |
@Suppress("UNCHECKED_CAST") | |
newPresenter as P | |
} | |
else -> { | |
@Suppress("UNCHECKED_CAST") | |
foundPresenter as P | |
} | |
} | |
} | |
fun <P : Presenter<V, R>, V, R> Fragment.getOrCreatePresenter(key: String): P { | |
return getOrCreatePresenter<P, V, R>(key, this as PresenterProvider) | |
} | |
fun <P : Presenter<V, R>, V, R> Fragment.getOrCreatePresenter(key: String, provider: PresenterProvider): P { | |
return fragmentManager.getOrCreatePresenter<P, V, R>(key, provider) | |
} | |
fun <P : Presenter<V, R>, V, R> FragmentActivity.getOrCreatePresenter(key: String): P { | |
return getOrCreatePresenter<P, V, R>(key, this as PresenterProvider) | |
} | |
fun <P : Presenter<V, R>, V, R> FragmentActivity.getOrCreatePresenter(key: String, provider: PresenterProvider): P { | |
return supportFragmentManager.getOrCreatePresenter<P, V, R>(key, provider) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.os.Bundle | |
interface StatefulPresenter { | |
fun saveState(state: Bundle) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment