Home > Mobile >  Previous fragment is not being replaced when selecting a navigation menu item
Previous fragment is not being replaced when selecting a navigation menu item

Time:09-26

I have a navigation drawer activity that shows a list of restaurants based on some data passed from the previous activity as the home fragment. On clicking on one of the restaurant cards, another fragment is created which shows the details of the restaurant. All of these fragments have the navigation drawer activity as their parent activity. When I am selecting the home fragment menu on the navigation item, the fragment does not replace the previous fragment rather it superimposes itself on the previous fragment. I will add some images to explain the scenario.

This is my Navigation Drawer - enter image description here

This is the home fragment containing the restaurant lists -

enter image description here

This is the fragment showing the restaurant details when clicking on one restaurant -

enter image description here

When I press the home item on the navigation drawer from the restaurant detail screen this happens -

enter image description here

Here is the relevant code- MainActivity2.class

package com.example.wfdmockapp;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;

import com.example.wfdmockapp.ui.home.HomeFragment;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;

import androidx.annotation.NonNull;
import androidx.core.view.GravityCompat;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;


import com.example.wfdmockapp.databinding.ActivityMain2Binding;

public class MainActivity2 extends AppCompatActivity{

    private static final String TAG = "MainActivity2";

    private String cityId = null;
    private String townId = null;

    private DrawerLayout drawer;

    private AppBarConfiguration mAppBarConfiguration;
    private ActivityMain2Binding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMain2Binding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.appBarMain.toolbar);
        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        drawer = binding.drawerLayout;
        NavigationView navigationView = binding.navView;
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home)
                .setOpenableLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        Intent getRestaurantIntent = getIntent();
        cityId = getRestaurantIntent.getStringExtra("cityId");
        townId = getRestaurantIntent.getStringExtra("townId");

        Bundle bundle = new Bundle();
        bundle.putString("cityId",cityId);
        bundle.putString("townId",townId);
        System.out.println(cityId " " townId);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .setReorderingAllowed(true)
                    .replace(R.id.nav_host_fragment_content_main, HomeFragment.class, bundle)
                    .commit();

        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_activity2, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}```






HomeFragment.Java

public class HomeFragment extends Fragment {

    private static final String TAG = "HomeFragment";

    private RequestQueue mRequestQueue;

    private String cityId = null;
    private String townId = null;
    private String ShopListUrl= Global.base_url "v1/get-shop-list";

    private ArrayList<Shop> shops = new ArrayList<>();

    private RecyclerView recyclerView;
    private ShopRecyclerViewAdapter adapter;

    private GifImageView loadingAnimation;

    @Override

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        Bundle bundle = this.getArguments();
        if(bundle!=null){
            cityId = bundle.getString("cityId");
            townId = bundle.getString("townId");
            System.out.println(cityId " " townId);
        }

        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mRequestQueue = Volley.newRequestQueue(getContext());

        loadingAnimation = view.findViewById(R.id.loading_animation);

        initRecyclerView(view);
        getShopList();
    }

    public void getShopList(){
        Log.d(TAG,"Creating Shop Object");
        JSONObject shopInfoObject = new JSONObject();

        try {
            shopInfoObject.put("city",cityId);
            shopInfoObject.put("town",townId);
            shopInfoObject.put("shop_type",null);
            shopInfoObject.put("api_token","a4e426652ed46154d67c8af897e77022");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Log.d(TAG,"JSON Shop Object created,collecting response for Request");
        JsonObjectRequest ShopListRequest = new JsonObjectRequest(Request.Method.POST, ShopListUrl, shopInfoObject, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {

                    Log.d(TAG,"Getting response");
                    JSONArray shopList = response.getJSONArray("shopList");

                    for(int i=0;i<shopList.length();i  ){
                        JSONObject jsonObject = shopList.getJSONObject(i);

                        Shop shop = new Shop();
                        shop.setShopId(jsonObject.getString("shopId"));
                        shop.setName(jsonObject.getString("title"));
                        shop.setTypeName(jsonObject.getString("typeName"));
                        shop.setLogo(Global.base_imageUrl jsonObject.getString("logo"));
                        shop.setSpecialOffer(jsonObject.getString("special_offer_text"));
                        shop.setDeliveredBy(jsonObject.getInt("deliveredBy"));
                        shop.setMixMatch(jsonObject.getInt("mixAndMatch"));
                        shop.setDeliveryFee(jsonObject.getString("delivery_fee"));
                        shop.setMinimumOrder(jsonObject.getString("minOrder"));
                        shop.setPaymentModeText(jsonObject.getString("paymentModeText"));
                        shop.setShopStatus(jsonObject.getString("currentStatus"));
                        shops.add(shop);
                    }

                    adapter.notifyDataSetChanged();
                    Log.d(TAG,"Shop data fetched");

                    loadingAnimation.setVisibility(View.GONE);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (error instanceof TimeoutError) {
                    Global.displayToast("Timeout! Please Try Again",getContext());
                }
            }
        });
        ShopListRequest.setRetryPolicy(new DefaultRetryPolicy(
                6000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        mRequestQueue.add(ShopListRequest);
    }

    public void initRecyclerView(View view){
        recyclerView = view.findViewById(R.id.recycler_view);
        adapter = new ShopRecyclerViewAdapter(shops,getContext(),this);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    }
}```

RestaurantDetailsFragment.Java

package com.example.wfdmockapp;

import android.graphics.drawable.Drawable;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
import com.example.wfdmockapp.models.Restaurant;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

import de.hdodenhof.circleimageview.CircleImageView;
import pl.droidsonroids.gif.GifImageView;

public class RestaurantDetailsFragment extends Fragment {

    private static final String TAG = "RestaurantDetails";

    private RequestQueue mRequestQueue;

    private Restaurant restaurant = new Restaurant();
    private String getShopDetailsUrl = Global.base_url "v1/get-shop-details";
    private String shopId;
    private ArrayList<String> FoodTypeList;

    //UI Components
    private TextView name;
    private TextView typeName;
    private TextView shopMessage;
    private TextView minOrder;
    private TextView paymentModeText;
    private RecyclerView foodTypeListRecyclerView;
    private FoodTypeRecyclerViewAdapter adapter;
    private TextView deliveryText;
    private TextView deliveryFee;
    private TextView deliveryTime;
    private TextView shopStatus;
    private CircleImageView shopLogo;
    private LinearLayout shopDetailsView;
    private GifImageView loadingAnimation;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        shopId = getArguments().getString("shopId");
    }

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        loadingAnimation = view.findViewById(R.id.shop_details_loading_animation);
        shopDetailsView = view.findViewById(R.id.shop_view);
        shopDetailsView.setVisibility(View.GONE);

        FoodTypeList = restaurant.getFoodTypeList();
        mRequestQueue = Volley.newRequestQueue(getContext());

        initRecyclerView(view);
        initUIComponents(view);
        showRestaurantDetails(view);
    }

    public void showRestaurantDetails(View view){
        JSONObject ShopInfoObject = new JSONObject();

        try {
            ShopInfoObject.put("api_token","cadbc10d3aa13257cd7c69bb3d434d00");
            ShopInfoObject.put("shopId",shopId);

        } catch (JSONException e) {
            e.printStackTrace();
        }


        JsonObjectRequest getShopDetailsRequest = new JsonObjectRequest(Request.Method.POST, getShopDetailsUrl, ShopInfoObject, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray shopDetails = response.getJSONArray("shop");

                    String deliveryTextResponse = response.getString("deliveryText");
                    restaurant.setDeliveryText(deliveryTextResponse);

                    for(int i=0;i<shopDetails.length();i  ){
                        JSONObject shopJsonObject = shopDetails.getJSONObject(i);

                        restaurant.setName(shopJsonObject.getString("title"));

                        restaurant.setTypeName(shopJsonObject.getString("typeName"));

                        restaurant.setShop_message(shopJsonObject.getString("shop_message"));

                        String ImageUrl = Global.base_imageUrl shopJsonObject.getString("logo");
                        restaurant.setLogo(ImageUrl);

                        restaurant.setMinOrder(shopJsonObject.getString("minOrder"));

                        restaurant.setStatus(shopJsonObject.getString("currentStatus"));

                        JSONArray foodTypeListJSONArray = shopJsonObject.getJSONArray("foodTypeList");
                        for(int j=0;j<foodTypeListJSONArray.length();j  ){
                            JSONObject foodTypeListJSONObject = foodTypeListJSONArray.getJSONObject(j);

                            Log.d(TAG,foodTypeListJSONObject.getString("foodTypeName"));
                            restaurant.addFoodListItems(foodTypeListJSONObject.getString("foodTypeName"));
                        }

                        adapter.notifyDataSetChanged();

                        restaurant.setDelivery_fee(shopJsonObject.getString("delivery_fee"));

                        JSONObject deliveryHours = shopJsonObject.getJSONObject("deliveryHours");
                        String openingHours = deliveryHours.getString("openingHour");
                        String closingHours = deliveryHours.getString("closingHour");
                        restaurant.setDeliveryTime("Delivery: " openingHours " - " closingHours);

                        restaurant.setPaymentModeText(shopJsonObject.getString("paymentModeText"));

                        setUIComponentValues(restaurant,view);

                        loadingAnimation.setVisibility(View.GONE);
                        shopDetailsView.setVisibility(View.VISIBLE);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (error instanceof TimeoutError) {
                    Global.displayToast("Timeout error!Please try again",getContext());
                }
            }
        });
        getShopDetailsRequest.setRetryPolicy(new DefaultRetryPolicy(
                5000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        mRequestQueue.add(getShopDetailsRequest);
    }

    public void initUIComponents(View view){
        name = view.findViewById(R.id.shopName);
        typeName = view.findViewById(R.id.shopTypename);
        shopMessage = view.findViewById(R.id.shop_message);
        minOrder = view.findViewById(R.id.min_order);
        paymentModeText = view.findViewById(R.id.payment_Method);
        deliveryFee = view.findViewById(R.id.min_delivery_fee);
        deliveryText = view.findViewById(R.id.delivery_time_today);
        deliveryTime = view.findViewById(R.id.shop_delivery_time);
        shopLogo = view.findViewById(R.id.shopLogo);
        shopStatus = view.findViewById(R.id.status);
    }

    public void setUIComponentValues(Restaurant restaurant,View view){
        Glide.with(getContext()).load(restaurant.getLogo()).into(shopLogo);
        name.setText(restaurant.getName());
        typeName.setText(restaurant.getTypeName());

        String message = restaurant.getShop_message();
        System.out.println(message);
        if(message.equals("")||message.equals("null")){
            Log.d(TAG,"No shop message,hiding field");
            LinearLayout shopMsgField = view.findViewById(R.id.shop_message_field);
            shopMsgField.setVisibility(View.GONE);
        }else{
            shopMessage.setText(message);
        }


        minOrder.setText("\u20ac " restaurant.getMinOrder() " MIN ");
        paymentModeText.setText(restaurant.getPaymentModeText());
        deliveryFee.setText("Delivery \u20ac " restaurant.getDelivery_fee());

        String text = restaurant.getDeliveryText();
        if(text.equals("null")||text.equals("")){
            deliveryText.setVisibility(View.GONE);
        }else{
            deliveryText.setText(text);
        }

        deliveryTime.setText(restaurant.getDeliveryTime());
        Global.setCurrentStatusText(restaurant.getStatus(),shopStatus);

    }

    public void initRecyclerView(View view){
        foodTypeListRecyclerView = view.findViewById(R.id.FoodTypeRecyclerView);
        adapter = new FoodTypeRecyclerViewAdapter(FoodTypeList,getContext());
        foodTypeListRecyclerView.setAdapter(adapter);
        foodTypeListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    }
}```

ShopRecyclerViewAdapter.java

package com.example.wfdmockapp;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.wfdmockapp.models.Shop;

import java.io.FileNotFoundException;
import java.util.ArrayList;

public class ShopRecyclerViewAdapter extends RecyclerView.Adapter<ShopRecyclerViewAdapter.ViewHolder> {

    private static final String TAG="ShopRecyclerViewAdapter";

    private ArrayList<Shop> shops;
    private Context  mContext;
    private Fragment fragment;

    public ShopRecyclerViewAdapter(ArrayList<Shop> shops,Context mContext,Fragment fragment) {
        this.shops = shops;
        this.mContext = mContext;
        this.fragment = fragment;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Log.d(TAG,"Reached onCreate");
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shoplistitem,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Log.d(TAG,"Reached onBind");
        try{
            Glide.with(mContext).load(shops.get(position).getLogo()).into(holder.shopLogo);
        }catch (Exception e){
            Glide.with(mContext).load(R.drawable.shop_logo_base).into(holder.shopLogo);
        }

        holder.deliveryFee.setText("Delivery \u20ac " shops.get(position).getDeliveryFee());
        holder.minOrder.setText("\u20ac " shops.get(position).getMinimumOrder() " MIN ");
        holder.paymentMethod.setText(shops.get(position).getPaymentModeText());

        String status = shops.get(position).getShopStatus();
        Global.setCurrentStatusText(status,holder.shopStatus);

        holder.shopName.setText(shops.get(position).getName());
        holder.shopTypeName.setText(shops.get(position).getTypeName());

        String offerText = shops.get(position).getSpecialOffer();
        if(!(offerText==null)){
            holder.shopOffer.setText(offerText);
        }else{
            holder.offerSection.setVisibility(View.GONE);
        }

        int deliveredBy = shops.get(position).getDeliveredBy();
        makeViewInvisible(holder.delivery_layout,deliveredBy);

        int mixAndMatch = shops.get(position).getMixMatch();
        makeViewInvisible(holder.mixMatchLayout,mixAndMatch);


        holder.parent_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                bundle.putString("shopId",shops.get(position).getShopId());

                FragmentManager fm = fragment.getActivity().getSupportFragmentManager();
                FragmentTransaction fragmentTrans = fm.beginTransaction();
                fragmentTrans.replace(R.id.nav_host_fragment_content_main,RestaurantDetailsFragment.class,bundle);
                fragmentTrans.setReorderingAllowed(true);
                fragmentTrans.addToBackStack(null);
                fragmentTrans.commit();
            }
        });
    }

    @Override
    public int getItemCount() {
        return shops.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
            ImageView shopLogo;
            TextView shopName;
            TextView shopTypeName;
            TextView shopOffer;
            TextView minOrder;
            TextView deliveryFee;
            TextView paymentMethod;
            TextView shopStatus;
            RelativeLayout offerSection;
            RelativeLayout parent_layout;
            RelativeLayout delivery_layout;
            RelativeLayout mixMatchLayout;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            shopLogo = itemView.findViewById(R.id.shop_logo);
            shopName = itemView.findViewById(R.id.shop_title);
            shopTypeName = itemView.findViewById(R.id.shop_typename);
            shopOffer = itemView.findViewById(R.id.offer_text);
            offerSection = itemView.findViewById(R.id.offer_section);
            minOrder = itemView.findViewById(R.id.shop_min_order);
            deliveryFee = itemView.findViewById(R.id.deliver_fee);
            shopStatus = itemView.findViewById(R.id.status);
            paymentMethod = itemView.findViewById(R.id.shop_payment);
            parent_layout = itemView.findViewById(R.id.parent_layout);
            delivery_layout = itemView.findViewById(R.id.delivered_by);
            mixMatchLayout = itemView.findViewById(R.id.mix_and_match);
        }
    }


    public void makeViewInvisible(View view,int flag){
        if(flag==1){
            view.setVisibility(View.GONE);
        }
    }

}```

CodePudding user response:

You need to pop the fragment onBackPressed and function needs to execute from MainActivity thus.

MainActivity

public void popFragment() {
    if (getSupportFragmentManager() == null)
        return;
    getSupportFragmentManager().popBackStack();
}


@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
        popFragment();
    }
}

CodePudding user response:

Turns out, the problem was in the ShopRecyclerViewAdapter.java file.

In the line

FragmentManager fm = fragment.getActivity().getSupportFragmentManager

fragment.getActivity made the context null. Grabbing context from view instead solved the problem.

I replaced the above line with the following:

FragmentManager fm = ((FragmentActivity) view.getContext()).getSupportFragmentManager()

Here is the reference to the solution:

Replace fragment from recycler adapter

  • Related