无法通过单击图像替换片段

Cannot replace fragment from a click on image

我有一个 navigationDrawer 和一个 Cardview 的 RecyclerView。我希望如果我点击 Cardview 上的图片,我的 Fragment 会发生变化,但什么也没有发生 这是代码:

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();
                }
            });
        }
    }
}

这是我要跳的class: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;
    }
}

问题出在onclick,尤其是在:

            public void onClick(View v) {

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

这是 mobile_navigation.xml

的 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>

谢谢

您正在创建新片段

Fragment frag = new InserisciSpesaFragment();

然后您正试图从中获取 Activity

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

此片段在 getActivity() 调用时未添加到任何 Activity,您应该在此处获得 NullPointerException...(崩溃,超过“没有任何反应")

考虑保留对构造函数

中获得的FragmentManager的引用
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();
    }

然后在 onClick 中使用它而不是尝试从 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();
        }

顺便说一句。我怀疑此代码是否有效,因为 R.id.nav_resoconto 是 XML 中已声明片段的 ID。 replace(...) method needs reference to fragment container view (in doc named containerViewId). read doc carefully 用于正确的导航切换