简体   繁体   中英

How to maintain fragment state when switching fragments

In my MainActivity class, I have a BottomNavigationView with 3 tabs that switch between activities (home, search, and personal). Whenever I click on any of the tabs, it pulls up the respective fragment, but I believe that I am calling a new fragment each and every time.

I need these fragments to maintain whatever changes are made in them (similarly to how Instagram does). Each fragment is currently very basic (newly created and unchanged), but I want to set them up in a way in which their states are saved when I switch to another fragment and restored when I go back to them.

Below is code for my main activity and the home fragment.

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView navigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView);
    navigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(R.id.content, new HomeFragment()).commit();
}

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener =
        new BottomNavigationView.OnNavigationItemSelectedListener(){
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item){
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                switch (item.getItemId()){
                    case R.id.HomeItem:
                        transaction.replace(R.id.content, new HomeFragment()).commit();
                        return true;
                    case R.id.SearchItem:
                        transaction.replace(R.id.content, new SearchFragment()).commit();
                        return true;
                    case R.id.PersonalItem:
                        transaction.replace(R.id.content, new PersonalFragment()).commit();
                        return true;
                }
                return false;
            }
        };
}


public class HomeFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

public HomeFragment() {
    // Required empty public constructor
}

// TODO: Rename and change types and number of parameters
public static HomeFragment newInstance(String param1, String param2) {
    HomeFragment fragment = new HomeFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_home, container, false);
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        Toast.makeText(context, "Home Fragment Attached", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}
}

You must use transaction.hide(fragment) and transaction.show(fragment) instead of transaction.replace, since replacing will delete the fragment and add it again, removing its saved state. Doing it my way will call fragments' onPause and onReaume method, not resetting their state.

Hope it helps!

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