Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.arellomobile.mvp.MvpDelegate
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.MapView
import com.google.android.gms.maps.OnMapReadyCallback
/**
* @author Konstantin Tskhovrebov (aka terrakok). Date: 01.03.17
*/
abstract class BaseMapFragment : Fragment(), OnMapReadyCallback {
private var isGoogleMapReady = false
private var isStateSaved = false
private val mvpDelegate: MvpDelegate<out BaseMapFragment> by lazy { MvpDelegate(this) }
protected lateinit var mapView: MapView
companion object {
private const val KEY_MAP_VIEW_OUT_STATE = "mapview_state"
}
/**
* Provide layout of the fragment
*/
@get:LayoutRes
protected abstract val fragmentLayout: Int
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mvpDelegate.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(fragmentLayout, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mapView = view.findViewById(R.id.mapView) as MapView
if (savedInstanceState == null) {
mapView.onCreate(null)
} else {
mapView.onCreate(savedInstanceState.getBundle(KEY_MAP_VIEW_OUT_STATE))
}
isGoogleMapReady = false
mapView.getMapAsync(this)
}
override fun onStart() {
super.onStart()
isStateSaved = false
if (isGoogleMapReady) {
mvpDelegate.onAttach()
}
}
override fun onResume() {
super.onResume()
isStateSaved = false
if (isGoogleMapReady) {
mvpDelegate.onAttach()
}
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
override fun onStop() {
super.onStop()
mvpDelegate.onDetach()
}
override fun onDestroyView() {
super.onDestroyView()
mvpDelegate.onDetach()
mvpDelegate.onDestroyView()
}
override fun onDestroy() {
super.onDestroy()
//We leave the screen and respectively all fragments will be destroyed
if (activity.isFinishing) {
mvpDelegate.onDestroy()
return
}
// When we rotate device isRemoving() return true for fragment placed in backstack
// http://stackoverflow.com/questions/34649126/fragment-back-stack-and-isremoving
if (isStateSaved) {
isStateSaved = false
return
}
if (isRemoving) {
mvpDelegate.onDestroy()
}
mapView.onDestroy()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
isStateSaved = true
mvpDelegate.onSaveInstanceState(outState)
mvpDelegate.onDetach()
val bundle = Bundle()
mapView.onSaveInstanceState(bundle)
outState.putBundle(KEY_MAP_VIEW_OUT_STATE, bundle)
}
override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
override fun onMapReady(googleMap: GoogleMap) {
isGoogleMapReady = true
mvpDelegate.onAttach()
}
}
@rsajob

This comment has been minimized.

Copy link

commented Apr 13, 2019

Данный вариант не корректно работает, когда происходит пересоздание вью без пересоздания фрагмента. Это происходит например при attach/detach (обычно исползуется для навигации по табам)

Суть вот в чём. При detach фрагмент (его инстенс) не унитчтожается, а остаётся висеть в памяти, но его view уничтожается. Вызывается onDestroyView() и при этом onSaveInstanceState() не вызывается и соответственно состояние mapView не сохраняется. Затем при attach у фрагмента уже не вызывается onCreate(), а сразу вызывается onCeateView() и получается так, что вью пересоздана без восстановления состояния.

Решил проблему добавлением специального поля mapBundle и при вызове onDestroyView() сохраняю состояние в него, а в onViewCreated() восстанавливаю если savedInstanceState == null.

Выложил в gist, там 2 варианта, c MapView (MvpMapViewFragment.kt) и c SupportMapFragment (MvpMapFragment). Кстати при использовании SupportMapFragment этой проблеы нет т.к. SupportMapFragment при этом уничтожается вместе со вью и сам заботится о восстановлени совего состояния состояния.

https://gist.github.com/rsajob/fbd6741e9e04d62d7e3185526d651805

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.