-1

this is my design

I am planning a 3 page map application. I have a map on my first page. bottom navigation reloads my map every time it is clicked. how can i prevent this?

My NavGraph

I cannot do this with transaction because there are too many subpages.

    <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/home">

    <include app:graph="@navigation/dashboard" />
    <include app:graph="@navigation/home" />
    <include app:graph="@navigation/menu" />
</navigation>

My Map Navgraph

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home"
app:startDestination="@id/homeFragment">

<fragment
android:id="@+id/homeFragment"
android:name="com.example.bottomnavwithnavigationcomponent.homeScreen.HomeFragment"
android:label="Home"
tools:layout="@layout/fragment_home" />

<fragment
    android:id="@+id/homeFragment2"
    android:name="com.example.bottomnavwithnavigationcomponent.homeScreen.HomeFragment2"
    android:label="Home"
    tools:layout="@layout/fragment_home2" />

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);

        NavigationUI.setupWithNavController(bottomNavigationView, navController);

        NavigationUI.setupActionBarWithNavController(this, navController);

    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return super.onSupportNavigateUp();
    }
}

Map Fragment

There is a trial fragment transition on this page. I want this page to never be refreshed.

public class HomeFragment extends Fragment {

    private OnMapReadyCallback callback = new OnMapReadyCallback() {

        @Override
        public void onMapReady(GoogleMap googleMap) {
            LatLng sydney = new LatLng(-34, 151);
            googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
        }
    };

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SupportMapFragment mapFragment =
                (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
        if (mapFragment != null) {
            mapFragment.getMapAsync(callback);
        }
    }
}

I did this with transaction, but it's very dysfunctional.

binding.navigationBottom.setOnItemSelectedListener(new BottomNavigationView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {


                if(menuItem.getItemId() == R.id.people){

                    removeFragment(tempFragment);
                }

                if(menuItem.getItemId() == R.id.group){

                    if (tempFragment ==null){
                        getFragment(groupFragment);
                    }
                    else {
                        removeFragment(tempFragment);
                        getFragment(groupFragment);
                    }
                    tempFragment = groupFragment;
                }

                if(menuItem.getItemId() == R.id.places){

                    if (tempFragment ==null){
                        getFragment(addFragment);
                    }
                    else {
                        removeFragment(tempFragment);
                        getFragment(addFragment);
                    }
                    tempFragment = addFragment;
                }
                if(menuItem.getItemId() == R.id.blank){

                    if (tempFragment ==null){
                        getFragment(blankFragment);
                    }
                    else {
                        removeFragment(tempFragment);
                        getFragment(blankFragment);
                    }
                    tempFragment = blankFragment;
                }
                if(menuItem.getItemId() == R.id.settings){
                    if (tempFragment ==null){
                        getFragment(settingsFragment);
                    }
                    else {
                        removeFragment(tempFragment);
                        getFragment(settingsFragment);
                    }
                    tempFragment = settingsFragment;


                }

                return true;
            }
        });

        binding.navigationBottom.setOnItemReselectedListener(new NavigationBarView.OnItemReselectedListener() {
            @Override
            public void onNavigationItemReselected(@NonNull MenuItem item) {

            }
        });
    }


    public void getFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        transaction.setCustomAnimations(R.anim.slide_up, 0);
        transaction.add(R.id.nav_host_fragment, fragment).addToBackStack(null).commit();
    }

    public void removeFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        transaction.remove(fragment).addToBackStack(null).commit();
    }

2 Answers2

1

Map is "refreshing" due of when you remove a fragment the one that removed fragment become destroyed, and then recreated and

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    SupportMapFragment mapFragment =
            (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    if (mapFragment != null) {
        mapFragment.getMapAsync(callback);
    }
}

with mapFragment.getMapAsync(callback); called again. You need to create a "map fragment" once and use hide() & show() methods from FragmentTransaction instead of add()/replace().

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
0

just Update your navigation component

/*Navigation Component dependencies*/
def nav_version = "2.4.0-alpha06"
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"