简体   繁体   中英

Handling Multiple Fragments when orientation changes

I have a MainActivity , and I want to attach a fragment with 3 buttons in it to that activity. On clicking button 1 it should replace this fragment with another fragment. But when I change orientation the current fragment and the old fragment are both getting attached. Can someone help me solve this ?

Following is my MainActivity.java :

public class MainActivity extends AppCompatActivity implements OnButtonsClickListener {

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


        getSupportFragmentManager().beginTransaction()
                .add(R.id.mainactivity, new FragmentHomepage(), "aboutMe")
                .commit();

    }




    @Override
    public void button1Action() {
        FragmentAboutMe fragmentAboutMe=new FragmentAboutMe();
        getSupportFragmentManager().beginTransaction()
                .add(R.id.mainactivity,fragmentAboutMe)
                .commit();
    }

    @Override
    public void button2Action() {
        Intent intent =new Intent(this,ActivityMasterDetail.class);
        startActivity(intent);
    }

    @Override
    public void button3Action() {
        Intent intent =new Intent(this,ActivityViewPager.class);
        startActivity(intent);
    }
}

This is my FragmentHomepage.java :

public  class FragmentHomepage extends Fragment {
    private static final String ARG_SECTION_NUMBER ="section number";
    OnButtonsClickListener onButtonsClickListener;
    public static FragmentHomepage newInstance(int sectionNumber){
        FragmentHomepage fragmentHomepage=new FragmentHomepage();
        Bundle args=new Bundle();
        args.putInt(ARG_SECTION_NUMBER,sectionNumber);
        fragmentHomepage.setArguments(args);
        return fragmentHomepage;
    }
    public FragmentHomepage(){}

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            onButtonsClickListener= (OnButtonsClickListener) context;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final Button button1= (Button) getActivity().findViewById(R.id.aboutMe);
        final Button button2= (Button) getActivity().findViewById(R.id.task2);
        final Button button3= (Button) getActivity().findViewById(R.id.task3);
        button1.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                onButtonsClickListener.button1Action();
            }
        });
        button2.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                onButtonsClickListener.button2Action();
            }
        });
        button3.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                onButtonsClickListener.button3Action();
            }
        });

    }

    @Nullable
    @Override
    public View onCreateView(final LayoutInflater inflater,
                             ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView=null;
        rootView =inflater.inflate(R.layout.fragment_homepage,container,false);
        return rootView;
    }
}

and my second activity is as follows (in FragmentAboutMe.java ):

public class FragmentAboutMe extends Fragment {
    int counters=0;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(savedInstanceState==null)counters=0;
        else counters=savedInstanceState.getInt("count");

    }

    @Override

    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("count",13);

    }

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

In your onCreate() method put a check whether the fragment is already present. Android automatically restores the fragment manager state upon orientation change and hence upon orientation change, the fragment which you added on button click would automatically be added. Thus if you will add new fragment in onCreate() without check, this would result in adding the 2 fragments. This is causing the issue.

FragmentManager fm = getSupportFragmentManager();

if (fm.findfragmentById(R.id.mainactivity) == null) {
     FragmentHomepage fragment = new FragmentHomepage ();
     fm.beginTransaction().add (R.id.mainactivity, fragment).commit();
}

You would want to save the state. You would need to extend Fragment to store the objects that need saving.

Override the onConfigurationChanged(..) and it should work out.

When I had to handle screen orientation changes, I recall having used this reference [ link ].

There are two ways.

Either you need to save the state in the bundle in onSaveInstanceState() method. Also save the states of fragment.

When activity recreate itself then check the value of bundle inside onCreate() or onRestoreInstanceState() method. Now initialize all the objects as before.

Else set the value of activity inside manifest file as

android:configChanges="layoutDirection|orientation|screenLayout|screenSize"

and override the method.

@Override
public void onConfigurationChanged(Configuration newConfig) {

}

Second technique will not allow the activity to restart on orientation change.

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