سؤال

I have a few fragments in my app, but my code opens a new fragment every time I click the button.

I want to know how can I change this, and make the fragment return to the exact same state I left it in.

The code im using right now:

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

        MainActivity fragment = new MainActivity();
        FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();
        transaction.add(R.id.fragment_place, fragment);
        transaction.commit();

        turnGPSOn();
    }

    public void onSelectFragment(View view) {

        if (view == findViewById(R.id.add)) 
        {
            newFragment = new Add();
        }
        else if (view == findViewById(R.id.map)) 
        {
            newFragment = new MainActivity();
        } 
        else 
        {
            newFragment = new Add();
        }

        FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();
        transaction.replace(R.id.fragment_place, newFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }

Thanks!

هل كانت مفيدة؟

المحلول

You are getting a new fragment each time because you are calling to new XXX() each time.

I think you could use findFragmentByTag in order to solve this problem. As you can see here the replace function can accept a third parameter that is a String, this String can be used as an id to identify different fragments you have used previously.

So to sum up you can:

  1. Call Fragment f = getSupportFragmentManager().findFragmentByTag("FragAdd"); for example in order to retrieve the first fragment.

  2. If f is null, that means that you haven't used that fragment yet, so you have to call to new Add() if not, use that fragment to replace the old one. For example like this:

FragmentTransaction transaction = getSupportFragmentManager()
            .beginTransaction();

transaction.replace(R.id.fragment_place, newFragment, "FragAdd"); //or whatever other string you want to use
transaction.addToBackStack(null);
transaction.commit();

Hope it helps :)

نصائح أخرى

I faced this issue a time ago, and managed to solve it for applications with one visible fragment at a time; for activities with several visible fragments, you'll need to make some adjustments. This is what I did.-

Create a custom ParentActivity, so that all my activities extend it. ParentActivity knows about which is the current Fragment that is showed, and how to show a new one.

public String currentFragmentTag;

public ParentFragment getCurrentFragment(int fragmentWrapperResId) { 
    ParentFragment res = null;  

    FragmentManager fragmentManager = getSupportFragmentManager();
    res = (ParentFragment) fragmentManager.findFragmentById(fragmentWrapperResId); 

    if (res != null && res.isHidden()) {
        if (currentFragmentTag != null) {
            res = (ParentFragment) fragmentManager.findFragmentByTag(currentFragmentTag);
        }
    }

    return res;
}

public void openFragment(ParentFragment fragment, int fragmentWrapperResId, int enterAnim, int exitAnim, int popEnterAnim, int popExitAnim, boolean addToBackStack) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    ParentFragment currentFragment = getCurrentFragment(fragmentWrapperResId);
    if (currentFragment != null && currentFragment.getTagName().equals(fragment.getTagName())) {
        return;
    }

    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim);

    if (currentFragment != null) {
        transaction.hide(currentFragment);
    }

    if (fragment.isAdded()) {
        transaction.show(fragment);
    } else {
        transaction.add(fragmentWrapperResId, fragment, fragment.getTagName()).setBreadCrumbShortTitle(fragment.getTagName());
    }

    if (addToBackStack) {
        transaction.addToBackStack(fragment.getTagName());
    } else {
        currentFragmentTag = fragment.getTagName();
    }

    transaction.commit();
}

Create a ParentFragment, to be extended by the rest of Fragments, with a tag getter

public String getTagName() {
    return getClass().getSimpleName() + System.identityHashCode(this);
}

As you can see, the main idea is not replacing visible fragments, but just adding them and show/hide whenever it's needed. This way, the fragments will keep their states, as they're not destroyed until you remove them from the bakstack.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top