0

In my app I use DrawerLayout. When I switch to MapFragment that contains SupportMapFragmentand go back to it Google Map is initialized again. Is there any way to stop Google Map from doing it ? I'm using Kotlin. I have read about idea of using WeakReference to MapView but I don't understand how it may help in this case.

class MapFragment : Fragment(), OnMapReadyCallback {

    lateinit var mMap: GoogleMap

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_map, container, false)
        val mapFragment = childFragmentManager.findFragmentById((R.id.map_new)) as SupportMapFragment
        mapFragment.getMapAsync(this)
        return view
    }

    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
    }


 val navigationView: NavigationView = findViewById(R.id.nav_view)
        navigationView.setNavigationItemSelectedListener {
            if(it.itemId == R.id.nav_logout){
                val intent = Intent(this, LoginActivity::class.java)
                startActivity(intent)
                true
            }
            else {
                var fragment = when (it.itemId) {
                    R.id.nav_map -> MapFragment()
                    R.id.nav_forecast -> ForecastFragment()
                    R.id.nav_app_info -> AboutFragment()
                    else -> MapFragment()
                }

                fragmentManager
                        .beginTransaction()
                        .replace(R.id.main_activity_frame, fragment)
                        .commit()
                it.isChecked = true
                drawerLayout.closeDrawers()
                true
            }
        }
dawzaw
  • 419
  • 6
  • 17

3 Answers3

1

Using the following methods allow you to perform any action when Fragment is switched off:

@Override
public void onDestroy() {
    super.onDestroy();
    //Anything you wish to do
}

@Override
public void onDetach() {
    super.onDetach();
    //Anything you wish to do
}
Ahmed Adaileh
  • 71
  • 1
  • 4
0

you have to stop fragment from recreating pages by this code :

   mViewPager.setOffscreenPageLimit(NumberOfYourPages);
Hadi Ahmadi
  • 129
  • 12
0

Setup you map this way,

Check if it is already not exist by findFragmentById(R.id.map_new) and then load fragment otherwise use already loaded.

childFragmentManager?.run {
        findFragmentById(R.id.map)?.let {
            val mapFragment = childFragmentManager.findFragmentById(R.id.map_new)
            if (mapFragment is SupportMapFragment) {
                mapFragment.getMapAsync(this@MapFragment)
            }
        }
    }

Edit:-

Here is activity oncreate:-

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.act_test)

    supportFragmentManager.beginTransaction()
            .replace(R.id.fragment, MapFragment.getInstance())
            .addToBackStack("MapFragment")
            .commit()

    btnBlank.setOnClickListener {
        val frag = supportFragmentManager.findFragmentById(R.id.fragment)
        if(frag !is BlankFragment) {
            supportFragmentManager.beginTransaction()
                    .replace(R.id.fragment, BlankFragment())
                    .addToBackStack("BlankFragment")
                    .commit()
        }
    }

    btnMap.setOnClickListener {
        supportFragmentManager.popBackStack("MapFragment", 0)
    }

}

And MapFragment:-

class MapFragment : Fragment(), OnMapReadyCallback {

private lateinit var map: GoogleMap

companion object {
    private val INSTANCE = MapFragment()
    fun getInstance() = INSTANCE
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater.inflate(R.layout.fragment_map, container, false)

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    childFragmentManager.run {
        findFragmentById(R.id.map)?.let {
            val mapFragment = childFragmentManager.findFragmentById(R.id.map)
            if (mapFragment is SupportMapFragment) {
                mapFragment.getMapAsync(this@MapFragment)
            }
        }
    }
}

override fun onMapReady(p0: GoogleMap?) {
    p0?.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(
            p0.cameraPosition.target.latitude,
            p0.cameraPosition.target.longitude
    ), 14f))
}


}
Randheer
  • 984
  • 6
  • 24
  • I tried it, but it didn't stop map from refreshing when I switch to MapFragment. – dawzaw May 16 '18 at 09:30
  • Maybe you are creating new MapFragment each time you are switching. Please share you code what are you doing on click from drawer menu. You need to reuse MapFragment instance there maybe by making MapFragment Singlaton. – Randheer May 16 '18 at 09:36
  • `companion object { private val INSTANCE = MapFragment() fun getInstance() = INSTANCE }` Add this to MapFragment and where you are using `MapFragment()` after click on drawer menu in NavigationItemListener, replace with `MapFragment.getInstance()` – Randheer May 16 '18 at 09:43
  • do let me know, if problem persist. – Randheer May 16 '18 at 09:56
  • It helps if I enter Map Fragment and then enter Map Fragment again - there is no reload. But when I switch to AboutFragment and come back - Map Fragment reloads again. – dawzaw May 16 '18 at 11:05
  • I created an activity for this, You need to manage you tab click with backstack in given way, I created this with two button Map and a Blank Fragment, Check my edited answer. – Randheer May 16 '18 at 11:36
  • Based on your idea I created method: `fun replaceMapFragment(fragment: MapFragment){ val fragmentName = fragment::class.java.simpleName val fragmentInBackStack = fragmentManager.popBackStackImmediate(fragmentName, 0) if (!fragmentInBackStack){ fragmentManager.beginTransaction() .replace(R.id.main_activity_frame, MapFragment.getInstance()) .addToBackStack(fragmentName) .commit() } }` Now there's now refresh if I come back to Map Fragment from another Fragment. – dawzaw May 16 '18 at 13:45