Reputation: 961
I have a main activity with many fragments that get replaced on each other and there state always get lost I even tried public void onSaveInstanceState(@NonNull Bundle outState)
but it still didn't work I even did it in the MainActivity
to retain the instance but still nothing
now I have a CartOrderFragment
that I add items to it from FoodListFragment
when a button is clicked, but every time I go to CartOrderFragment
and come back to FoodListFragment
and try to add more item by clicking on the same button before, the CartOrderFragment
lose its list.
MainActivity.java
public class MainActivity extends AppCompatActivity implements
SetupAccountFragment.SetupAccountListener, FoodListFragment.ListenerFoodListFragment,
SignInAccountFragment.SignInAccountListener, SignUpAccountFragment.SignUpAccountListener {
FragmentManager fm;
FoodListFragment foodListFragment;
ArrayList<Food> foodsOrdered;
CartOrdersFragment cartOrdersFragment;
Map<Integer, Integer> cartValues = new HashMap<>();
@Override
public void sendOrders(ArrayList<Food> foods) {
foodsOrdered = foods;
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "myFragment", cartOrdersFragment);
}
// this get called when the button gets clicked in the FoodListFragment
@Override
public void cartClickListener() {
cartOrdersFragment = CartOrdersFragment.newInstance(foodsOrdered);
fm.beginTransaction()
.replace(R.id.main_container, cartOrdersFragment)
.addToBackStack(null)
.commit();
}
// for sign up fragment
@Override
public void registerNowBtnListener() {
foodListFragment = new FoodListFragment();
fm.beginTransaction()
.replace(R.id.main_container, foodListFragment)
.commit();
}
// for sign up fragment
// for sign in fragment
@Override
public void signInBtn() {
foodListFragment = new FoodListFragment();
fm.beginTransaction()
.replace(R.id.main_container, foodListFragment)
.commit();
}
// for sign in fragment
@Override
public void sendToCart(int value, int adapterPosition) {
cartValues.put(adapterPosition, value);
foodListFragment.updateCartValue(getTotalValue());
}
private int getTotalValue() {
int value = 0;
for (Integer key : cartValues.keySet()) {
value += cartValues.get(key);
}
return value;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
cartOrdersFragment = (CartOrdersFragment) getSupportFragmentManager().getFragment(savedInstanceState,
"myFragment");
}
fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.main_container);
if (fragment == null) {
// adding fragment to main container
fm.beginTransaction()
.replace(R.id.main_container, onBoardingFragment)
.replace(R.id.id_container_menu, new FoodCategoryFragment())
.addToBackStack(null)
.commit();
}
}
}
CartOrderFragment.java
public class CartOrdersFragment extends Fragment {
private CartOrdersAdapter cartOrdersAdapter;
private ArrayList<Food> foods;
private static final String KEY_ARRAYLIST = "ArrayList";
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(KEY_ARRAYLIST, foods);
}
public static CartOrdersFragment newInstance(ArrayList<Food> foods) {
CartOrdersFragment cartOrdersFragment = new CartOrdersFragment();
Bundle args = new Bundle();
args.putParcelableArrayList(KEY_ARRAYLIST, foods);
cartOrdersFragment.setArguments(args);
return cartOrdersFragment;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
foods = savedInstanceState.getParcelableArrayList(KEY_ARRAYLIST);
}
if (getArguments() != null) {
foods = getArguments().getParcelableArrayList(KEY_ARRAYLIST);
}
cartOrdersAdapter = new CartOrdersAdapter(getActivity(), foods);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(cartOrdersAdapter);
}
public class FoodListFragment extends Fragment {
private FoodListAdapter foodListAdapter;
private BadgeHolderLayout badgeHolderLayout;
private ArrayList<Food> foods;
public interface ListenerFoodListFragment {
void sendToCart(int value, int adapterPosition);
void cartClickListener();
void sendOrders(ArrayList<Food> foods);
}
private ListenerFoodListFragment listenerFoodListFragment;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
listenerFoodListFragment = (ListenerFoodListFragment) context;
} catch (ClassCastException e) {
Log.d("FoodListFragment", "onAttach: " + e.getMessage());
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
foods = new ArrayList<>();
foods.add(new Food("Chicken", "99999$", R.drawable.chicken));
foods.add(new Food("Burger", "1000$", R.drawable.burger));
badgeHolderLayout.setOnClickListener(v -> listenerFoodListFragment.cartClickListener());
foodListAdapter = new FoodListAdapter(getActivity(), foods, listenerFoodListFragment);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(foodListAdapter);
}
public void updateCartValue(int value) {
badgeHolderLayout.setCountWithAnimation(value);
}
}
FoodListAdapter.java
public class FoodListAdapter extends RecyclerView.Adapter<FoodListAdapter.ViewHolder>
implements Filterable {
private Context context;
private List<Food> foodList;
private List<Food> foodListFiltered;
private ArrayList<Food> orderedFood = new ArrayList<>();
FoodListFragment.ListenerFoodListFragment listenerFoodListFragment;
public FoodListAdapter(Context context, List<Food> foodList,
FoodListFragment.ListenerFoodListFragment listenerFoodListFragment) {
this.context = context;
this.foodList = foodList;
this.listenerFoodListFragment = listenerFoodListFragment;
this.foodListFiltered = foodList;
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(@NonNull View itemView) {
super(itemView);
// this is the button that i mentioned
tvOk.setOnClickListener(v -> {
Food food = foodList.get(getAdapterPosition());
orderedFood.add(food);
listenerFoodListFragment.sendOrders(orderedFood);
});
fc.setOnClickListener(v -> fc.toggle(false));
}
}
}
Upvotes: 0
Views: 500
Reputation: 59
you can use hide and show, try this
protected void onCreate(Bundle savedInstanceState){
fm.beginTransaction()
.add(R.id.main_container, fragmentOne)
.add(R.id.main_container, fragmentTwo)
.hide(fragmentTwo)
.addToBackStack(null)
.commit();
}
private void onBtnTwoClick() {
fm.beginTransaction().show(fragmentTwo).hide(fragmentOne)
.addToBackStack(null).commit();
}
private void onBtnOneClick() {
fm.beginTransaction().show(fragmentOne).hide(fragmentTwo)
.addToBackStack(null).commit();
}
here is the way with replace
you need a StateHelper
public class FragmentStateHelper {
private HashMap<String, Fragment.SavedState> fragmentStates;
private FragmentManager fragmentManager;
public FragmentStateHelper(FragmentManager fragmentManager) {
fragmentStates = new HashMap<>();
this.fragmentManager = fragmentManager;
}
public void restoreState(Fragment fragment, String key) {
Fragment.SavedState savedState = fragmentStates.get(key);
if (savedState != null) {
if (!fragment.isAdded()) {
fragment.setInitialSavedState(savedState);
}
}
}
public void saveState(Fragment fragment, String key) {
if (fragment.isAdded()) {
fragmentStates.put(key, fragmentManager.saveFragmentInstanceState(fragment));
}
}
}
save old fragment and restore new one before replace.
@Override
public void signInBtn() {
//save state here
foodListFragment = new FoodListFragment();
//restore foodListFragment here
fm.beginTransaction()
.replace(R.id.main_container, foodListFragment)
.commit();
}
you need save and restore in fragment
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY, str);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null) {
str = savedInstanceState.getString(KEY);
}
}
you can check here: https://medium.com/@bherbst/saving-fragment-state-yourself-522c3bca78c7
hope it help and happy new year.
Upvotes: 1