RM3
RM3

Reputation: 107

Cannot get one fragment to replace another on a button click

Currently working my way through the Android Developer pages. On runtime I have a fragment that is put into place with a button that say click. What I want to do is have that button simply change the fragment to a different one that I have constructed. Right now, nothing happens when clicked.

public class Menu_Fragment extends Fragment {

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

    final Button button = (Button) view.findViewById(R.id.button_to_click);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Click_Fragment nextFrag = new Click_Fragment();
            FragmentTransaction trans = getFragmentManager().beginTransaction();

            trans.replace(R.id.fragment_container, nextFrag);
            trans.addToBackStack(null);

            trans.commit();
        }
    });
    return view;
  }
}

The button is written into Menu_Fragment's XML and has the corresponding id. My feeling is that is has to do with the return view; at the end, but I am unsure about that and wouldn't know how to change that. Any and all help is appreciated. If you can and are willing to just point me in the right direction, that is even better than a hard code solution.

Edit:

In case the issue is with the MainActivity, here is its code:

public class MainActivity extends FragmentActivity {

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

    if (findViewById(R.id.fragment_container) != null) {

        if (savedInstanceState != null) {
            return;
        }

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        Menu_Fragment fragment = new Menu_Fragment();
        fragment.setArguments(getIntent().getExtras());

        ft.replace(R.id.fragment_container, fragment);
        ft.commit();

      }
   }
}

Upvotes: 1

Views: 492

Answers (3)

Androider
Androider

Reputation: 3873

Use following approach to avoid your problems:

String TAG="fragmentFirst";

  // to replace
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.fragment_container, mFragment, TAG)
            .commit();

    //find by tag as needs    
    Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG);

Upvotes: 0

Sajib Acharya
Sajib Acharya

Reputation: 1733

A very simple and straight-forward way to achieve what you want is to provide an onClick attribute to the <Button> element in the XML and since you have the button in the XML, I suggest you give it an onClick attribute, like onClick="replaceFragment" and in your activity containing the fragment, simply provide a method public void replaceFragment(View view){...}. This method will be called when the button is clicked and must reside within the activity holding the fragment. The best practice is to use a tag on the fragment while replacing it to avoid recreating similar fragments and instead just replacing them. This is a problem I faced a lot of times. But that is just your choice. Then you can use something like:

if(fragment != null) {
            savedFragment = getFragmentManager().findFragmentByTag(TAG);
            FragmentTransaction ft = getFragmentManager().beginTransaction();

            if(savedFragment != null) {
                ft.replace(R.id.content_frame_id, savedFragment, TAG);
            }
            else {
                ft.replace(R.id.content_frame_id, fragment, TAG);
            }

            ft.addToBackStack(null);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.commit();
        }

Where fragment is your original fragment object like Fragment fragment = new AnyNewFragmentClass().

What this does is it searches whether the fragment you are trying to create has already been created, and thus uses it instead of just creating a brand new fragment object. If no fragment is already created, i.e., savedFragment == null, then a brand new fragment is created. This is especially useful while maintaining orientation changes. Hope this helps. If you are unable to understand any part, do ask. :)

Upvotes: 1

Muhammad Naderi
Muhammad Naderi

Reputation: 3248

for nested fragments you should use getChildFragmentManager()

Edit:

On the other hand, if you need to change the fragment in the main activity, you either need to get main Activities Fragment manager by using

getActivity().getSupportFragmentManager().beginTransaction...

or make a public method in the main Activity, to change the fragment and call it from the Child Fragment by using

getActivity().ChangeFragment();

and in the main Activity

public void ChangeFragment(){
            FragmentTransaction trans = getFragmentManager().beginTransaction();

            trans.replace(R.id.fragment_container, nextFrag);
            trans.addToBackStack(null);

            trans.commit();
}

Upvotes: 0

Related Questions