Home > Enterprise >  Cannot replace fragment from a click on image
Cannot replace fragment from a click on image

Time:02-11

I have a navigationDrawer and a RecyclerView of a Cardview. I want that if I click on an image on Cardview, my Fragment changes, but nothing happens This is the code:

CardAdapter.java

public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {

    // Constructor
    public CardAdapter(
            FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
        super(options);
    }

    @Override
    protected void
    onBindViewHolder(@NonNull cardViewholder holder,
                     int position, @NonNull Spesa model)
    {

        holder.amount.setText(model.getDesc());
        holder.who.setText(String.valueOf(model.getCosto()));
        holder.Description.setText(model.getCategoria());
        holder.modifica.setImageResource(R.drawable.edit);

        String str = model.getchi();
        if(model.getchi().equals("Francesco")){
            holder.chiSpende.setImageResource(R.drawable.fra);
        }
        else if(model.getchi().equals("Angela")){
            holder.chiSpende.setImageResource(R.drawable.angela);
        }
holder.modifica.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AppCompatActivity activity = (AppCompatActivity) v.getContext();
                Fragment myFragment = new InserisciSpesaFragment();
                activity.getSupportFragmentManager().beginTransaction().replace(R.id.nav_resoconto, myFragment).addToBackStack(null).commit();

            }
    }

    @NonNull
    @Override
    public cardViewholder
    onCreateViewHolder(@NonNull ViewGroup parent,
                       int viewType)
    {
        View view
                = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_layout, parent, false);
        return new CardAdapter.cardViewholder(view);
    }


    class cardViewholder extends RecyclerView.ViewHolder {
        CardView cw;
        TextView amount, who, Description;
        ImageView chiSpende, cancella, modifica;
        public cardViewholder(@NonNull View itemView)
        {
            super(itemView);
            amount = itemView.findViewById(R.id.idAmount);
            who = itemView.findViewById(R.id.idChiSpende);
            Description = itemView.findViewById(R.id.idDescrizioneSpesa);
            chiSpende = itemView.findViewById(R.id.ImgSpese);
            cancella = itemView.findViewById(R.id.bin);
            modifica = itemView.findViewById(R.id.edit);
            cw = itemView.findViewById(R.id.myCardView);

            });

            modifica.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    AppCompatActivity activity = (AppCompatActivity) v.getContext();
                    Fragment frag = new InserisciSpesaFragment();
                    activity.getSupportFragmentManager().beginTransaction()
                            .replace(R.id.nav_resoconto, frag).commit();
                }
            });
        }
    }
}

this is the class in which I want to jump: InserisciSpesaFragment.java

public class InserisciSpesaFragment extends Fragment {
   private Firebase mref;
    FirebaseDatabase database = FirebaseDatabase.getInstance();

    private InserisciSpesa inserisciSpesa;
    private FragmentInserisciBinding binding;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        inserisciSpesa =
                new ViewModelProvider(this).get(InserisciSpesa.class);
        binding = FragmentInserisciBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        Button btn = (Button) binding.BtnInsert;
        EditText txtcosto = (EditText) binding.EdittextCosto;
        EditText txtdesc = (EditText) binding.EdittextSpesa;
        Spinner spinCat = (Spinner) binding.spinnerCategorie;
        Spinner spinChi = (Spinner) binding.spinnerChi;
        DatePicker datePicker = (DatePicker) binding.DatePicker;

       ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                String my = (String) snapshot.getValue();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        };
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(!CampiVuoti(txtdesc.getText().toString(), txtcosto.getText().toString())){
                    Snackbar.make(view, "Attenzione, sono presenti campi vuoti!", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                }
                else {
                    Spesa spesa = new Spesa(txtdesc.getText().toString(), Double.parseDouble(txtcosto.getText().toString()),
                            spinCat.getSelectedItem().toString(), spinChi.getSelectedItem().toString(),
                            datePicker.getDayOfMonth(), datePicker.getMonth()   1, datePicker.getYear());
                    addDatatoFirebase(spesa);
                    Snackbar.make(view, "Spesa inserita correttamente", Snackbar.LENGTH_LONG)
                            .setAction("Action", null).show();
                }
            }
        });

        inserisciSpesa.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                //textView.setText(s);
            }
        });
        return root;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

The problem is in the onclick, Especially in:

            public void onClick(View v) {

                Fragment frag = new InserisciSpesaFragment();
                FragmentManager fm = frag.getActivity().getSupportFragmentManager();
                fm.beginTransaction()
                        .replace(R.id.nav_resoconto, frag)
                        .commit();
            }

Thisi is the xml file of the mobile_navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@ id/mobile_navigation"
    app:startDestination="@ id/nav_home">

    <fragment
        android:id="@ id/nav_home"
        android:name="com.example.frangela.ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@ id/nav_gallery"
        android:name="com.example.frangela.ui.gallery.GalleryFragment"
        android:label="@string/menu_gallery"
        tools:layout="@layout/fragment_gallery" />

    <fragment
        android:id="@ id/nav_slideshow"
        android:name="com.example.frangela.ui.slideshow.InserisciSpesaFragment"
        android:label="@string/menu_slideshow"
        tools:layout="@layout/fragment_inserisci" />
    <fragment
        android:id="@ id/nav_stipendio"
        android:name="com.example.frangela.ui.stipendio.InserisciStipendioFragment"
        android:label="@string/menu_stipendio"
        tools:layout="@layout/fragment_stipendio" />

    <fragment
        android:id="@ id/nav_resoconto"
        android:name="com.example.frangela.ui.resocard.ResocardFragment"
        android:label="@string/Resoconto"
        tools:layout="@layout/fragment_resocard" />

</navigation>

Thanks

CodePudding user response:

you are creating new fragment

Fragment frag = new InserisciSpesaFragment();

and just after that you are trying to obtain an Activity from it

FragmentManager fm = frag.getActivity().getSupportFragmentManager();

this fragment isn't added to any Activity at the moment of this getActivity() call, you should get an NullPointerException in here... (crash, more than "nothing happens")

consider keeping reference to FragmentManager obtained in constructor

public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {

    private FragmentManager fm;

    // Constructor
    public CardAdapter(FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
        super(options);
        fm = activity.getSupportFragmentManager();
    }

and then in onClick just use it instead of trying to get it from not-added Fragment

       public void onClick(View v) {
            Fragment frag = new InserisciSpesaFragment();
            //FragmentManager fm = frag.getActivity().getSupportFragmentManager();
            fm.beginTransaction() // use fm obtained in constructor
                    .replace(R.id.nav_resoconto, frag)
                    .commit();
        }

btw. I doubt this code will work as R.id.nav_resoconto is an id of already declared fragment in XML. replace(...) method needs reference to fragment container view (in doc named containerViewId). read doc carefully for proper navigation switching

  • Related