简体   繁体   中英

.replace not Working as Expected

I am trying to to a Bottom Navigation View that has a Fragment per item. my code to change in between Fragment is as follows:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_host, container, false);

    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
    ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);

    fm = getActivity().getSupportFragmentManager();
    final BottomNavigationView bottomNavigationView = (BottomNavigationView)
            view.findViewById(R.id.navigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment selectedFragment;
            FragmentTransaction transaction = fm.beginTransaction();
            switch (item.getItemId()){
                case R.id.countries_bottom:
                    selectedFragment = fm.findFragmentByTag(COUNTRIES_TAG);
                    // If fragment doesn't exist yet, create one
                    if (selectedFragment == null) {
                        transaction.add(R.id.frame_layout, new CountriesFragment(), COUNTRIES_TAG);
                        Log.d("FRAGMENTS",  "COUNTRIES CREATED");
                    }
                    else { // re-use the old fragment
                        transaction.replace(R.id.frame_layout, selectedFragment, COUNTRIES_TAG);
                        Log.d("FRAGMENTS",  "COUNTRIES REPLACED");
                    }
                    break;
                case R.id.cities_bottom:
                    selectedFragment = fm.findFragmentByTag(CITIES_TAG);
                    // If fragment doesn't exist yet, create one
                    if (selectedFragment == null) {
                        transaction.add(R.id.frame_layout, new CitiesFragment(), CITIES_TAG);
                        Log.d("FRAGMENTS",  "CITIES CREATED");
                    }
                    else { // re-use the old fragment
                        transaction.replace(R.id.frame_layout, selectedFragment, CITIES_TAG);
                        Log.d("FRAGMENTS",  "CITIES REPLACED");
                    }
                    break;
                case R.id.places_bottom:
                    selectedFragment = fm.findFragmentByTag(PLACES_TAG);
                    // If fragment doesn't exist yet, create one
                    if (selectedFragment == null) {
                        transaction.add(R.id.frame_layout, new PlacesFragment(), PLACES_TAG);
                        Log.d("FRAGMENTS",  "PLACES CREATED");
                    }
                    else { // re-use the old fragment
                        transaction.replace(R.id.frame_layout, selectedFragment, PLACES_TAG);
                        Log.d("FRAGMENTS",  "PLACES REPLACED");
                    }
                    break;
            }
            transaction.commit();
            return true;
        }
    });

    return view;
}

When I do it they do run, but it is odd sometimes. Lets call them 1, 2, 3. When I am in 1, and go to 2, the log says "CREATED" so 2 gets created, yet 1 is still visible in the back. Then, when I go back to 1, it says "REPLACED" and it looks fine. but then, I re-go back to two and instead of saying "REPLACED" it says "CREATED" again, so I am not sure how replace is working in this case, how can I do so I can only have 1 instance of each fragment?

to make it a little more odd, if I go from 1, to 2 and then 3, then when I go back to 1, 1 would not be "REPLACED" but instead "CREATED" again.

EDIT: So searching I learned that replacing will remove my fragment completely from the stack, so what I decided was to instead of replacing, showing the fragment and hiding the rest of them if they exist. Even though this does fix the issue and the app basically does what I am looking for, I'm sure this is not the best solution.

Here is an example of the quick change I did:

case R.id.countries_bottom:
                    selectedFragment = fm.findFragmentByTag(COUNTRIES_TAG);
                    // If fragment doesn't exist yet, create one
                    if (selectedFragment == null) {
                        transaction.add(R.id.frame_layout, new CountriesFragment(), COUNTRIES_TAG);
                        Log.d("FRAGMENTS",  "COUNTRIES CREATED");
                    }
                    else { // re-use the old fragment
                        transaction.show(selectedFragment);
                        Log.d("FRAGMENTS",  "COUNTRIES REPLACED");
                    }
                    if(fm.findFragmentByTag(CITIES_TAG) != null )
                        transaction.hide(fm.findFragmentByTag(CITIES_TAG));
                    if(fm.findFragmentByTag(PLACES_TAG) != null )
                        transaction.hide(fm.findFragmentByTag(PLACES_TAG));
                    transaction.commit();
                    break;

but then, I re-go back to two and instead of saying "REPLACED" it says "CREATED" again.

I'm not 100% sure, but this happens because when you go back to fragment 1, the fragment 2 is removed from the backstack and no longer exists.

to make it a little more odd, if I go from 1, to 2 and then 3, then when I go back to 1, 1 would not be "REPLACED" but instead "CREATED" again.

// Works with either the framework FragmentManager or the
// support package FragmentManager (getSupportFragmentManager).
getSupportFragmentManager().beginTransaction()
                           .add(detailFragment, "detail")
                           // Add this transaction to the back stack
                           .addToBackStack()
                           .commit();

As you can see, there is a .addToBackStack() method. I suggest using this method when you add a fragment.

This code was removed from documentation: https://developer.android.com/training/implementing-navigation/temporal.html

Hope I had help you with something.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM