Search code examples
androidfragmentlifecycle

Fragments switching and lifecycle


I'm trying to implement a NavigationDrawer with fragments on a frame layout in the main activity. the navigation drawer should switch between my "main" fragment, a GMAP fragment , and some other fragment. being the "main" fragment , this fragment is also added when the activity first startup (as you can see in the code). the problem is when i replace the fragments on items click, the fragments are being destroyed and the map fragment is being created all over again. i would much prefer the fragment to be created once and somehow save its states when i replace it with other fragments on top of the place holder

this is the map fragment :

public class Mapfragment extends Fragment
{
MapView mMapView;
private GoogleMap googleMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // inflate and return the layout
    View v = inflater.inflate(R.layout.activity_map_fragment, container,
            false);
    mMapView = (MapView) v.findViewById(R.id.mapView);
    mMapView.onCreate(savedInstanceState);

    mMapView.onResume();// needed to get the map to display immediately

    try {
        MapsInitializer.initialize(getActivity().getApplicationContext());
    } catch (Exception e) {
        e.printStackTrace();
    }
    Camera camera = UserDetails.getInstance().getCameras().get(0);

    googleMap = mMapView.getMap();
    // latitude and longitude
    double latitude = camera.getLatitude();
    double longitude = camera.getLongitude();

    // create marker
    MarkerOptions marker = new MarkerOptions().position(
            new LatLng(latitude, longitude)).title("Hello Maps");

    // Changing marker icon
    marker.icon(BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

    // adding marker
    googleMap.addMarker(marker);
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(camera.getLatitude(), camera.getLongitude())).zoom(18).build();
    googleMap.animateCamera(CameraUpdateFactory
            .newCameraPosition(cameraPosition));

    // Perform any camera updates here
    return v;
}@Override
 public void onResume() {
super.onResume();
Log.d("Map fragment Resumed", "sdfsdf");
mMapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    Log.d("Map fragment paused","dsffs");
    mMapView.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d("Map fragment Destroyed", "sdfsdf");
    mMapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mMapView.onLowMemory();
}

}

and the main activity

public class Main_screen extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_screen);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    Fragment fragment  = new Mapfragment();




    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    View hView =  navigationView.getHeaderView(0);
    TextView username_header = (TextView)hView.findViewById(R.id.username_header);
    username_header.setText(UserDetails.getInstance().getUsername());
    ImageView img= (ImageView)hView.findViewById(R.id.imageView);
    img.setImageBitmap(UserDetails.getInstance().getImage());
            //adding main fragment upon Main screen activity Oncreate
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().add(R.id.frame_layout_placeholder,fragment).commit();





}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main_screen, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    android.support.v4.app.Fragment fragment = null;
    android.support.v4.app.FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction();

    int id = item.getItemId();

    if (id == R.id.map_frag_item) {
        fragment  = new Mapfragment();
    } else if (id == R.id.nav_gallery) {
        fragment = new FragmentTwo();

    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {
    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }

    fragmentManager.replace(R.id.frame_layout_placeholder, fragment).commit();
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

the main GMAP fragment is being added on the OnCreate of the activity and the garments are being replaced on the OnItemSelected(). thank you very much!


Solution

  • It looks like in onNavigationItemSelectedyou are creating new fragments each time. I think what you want to do is this:

    1. First check if you already have a fragment. This can be done using findFragmentByTag() on the fragment manager.
    2. If it returns null, then you have not created the fragment yet, in which case you create the new fragment and then add it with some tag (the one you will use to search for it when you call findFragmentByTag() next time).

    3. If it does exist then you can replace the current fragment with the one you found.

    When you create the fragment, in the onCreate method, you might also want to call setRetainInstance(true)