Home > Back-end >  how do i access getParentFragmentManager() from inside an adapter
how do i access getParentFragmentManager() from inside an adapter

Time:08-11

am trying to send a one time data from one a recyclerView adapter to a fragment in order to check which button was presses. according to the official documentation for this case it is best to use a getParentFragmentManager() method to interact with the fragment but i can only access it from a fragment and not from an adapter here is a copy of my adapter code :

public class MusclesListAdapter extends RecyclerView.Adapter<MusclesListAdapter.MuscleViewHolder> {
private Context context;
private List<MusclesKeys> musclesKeysList;

public MusclesListAdapter(Context context, List<MusclesKeys> musclesKeysList) {
    this.context = context;
    this.musclesKeysList = musclesKeysList;
}

@NonNull
@Override
public MuscleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.muscle_group_row, parent, false);
    return new MuscleViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MuscleViewHolder holder, int position) {
    holder.muscleBtn.setImageResource(musclesKeysList.get(position).image);
    holder.muscleBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MusclesFragment frg = new MusclesFragment();
            ExercisesFragment fragment = new ExercisesFragment();
            AppCompatActivity activity = (AppCompatActivity) view.getContext();
            Bundle bundle = new Bundle();
            bundle.putString("muscleName", musclesKeysList.get(position).getKey().toString());
            frg.getParentFragmentManager().setFragmentResult("muscleKey", bundle);
            activity.getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragmentContainerView, fragment, null).addToBackStack(null).commit();
        }
    });

}


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

public class MuscleViewHolder extends RecyclerView.ViewHolder {
    ImageView muscleBtn;

    public MuscleViewHolder(@NonNull View itemView) {
        super(itemView);
        muscleBtn = itemView.findViewById(R.id.muscle_btn);

    }
}

and here is a copy of my receiving fragment code :

public class ExercisesFragment extends Fragment {
private List<ExercisesKeys> exercisesList;
private RecyclerView recyclerView;
private String muscleKey;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_exercises, container, false);

    exercisesList = new ArrayList<>();
    recyclerView = v.findViewById(R.id.exercises_rv);
    recyclerView.setLayoutManager(new LinearLayoutManager(container.getContext()));
    recyclerView.setHasFixedSize(true);
    getParentFragmentManager().setFragmentResultListener("muscleKey", this, new FragmentResultListener() {
        @Override
        public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
            muscleKey = result.getString("muscleName");
        }
    });
    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
    switch (muscleKey){
        case "pecs":
            databaseReference.child("pecs");
            databaseReference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    exercisesList.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        ExercisesKeys exercisesKeys = new ExercisesKeys(dataSnapshot.getValue().toString());
                        exercisesList.add(exercisesKeys);
                    }
                    ExercisesListAdapter adapter = new ExercisesListAdapter(container.getContext(), exercisesList);
                    recyclerView.setAdapter(adapter);
                    adapter.notifyDataSetChanged();

                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(container.getContext(), "fail0", Toast.LENGTH_SHORT).show();
                }
            });

        case  "shoulders":
            databaseReference.child("shoulders");
            databaseReference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    exercisesList.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        ExercisesKeys exercisesKeys = new ExercisesKeys(dataSnapshot.getValue().toString());
                        exercisesList.add(exercisesKeys);
                    }
                    ExercisesListAdapter adapter = new ExercisesListAdapter(container.getContext(), exercisesList);
                    recyclerView.setAdapter(adapter);
                    adapter.notifyDataSetChanged();

                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(container.getContext(), "fail0", Toast.LENGTH_SHORT).show();
                }
            });
    }

    return v;
}

i have tried to access the method by creating an instance of the adapter's fragment as you can see , and although it did give me access to the method but every time i use the app it crashes and i get this error

at com.sissou.dev.gymapp.Model.MusclesListAdapter$1.onClick(MusclesListAdapter.java:48)

CodePudding user response:

use interface

interface MusclesListAdapteListener {
    void onClickItem();
}

add parameter to your constructor adapter, also global variable in adapter

   MusclesListAdapteListener musclesListAdapteListener;
   public MusclesListAdapter(MusclesListAdapteListener musclesListAdapteListener , List<MusclesKeys> musclesKeysList) {
     this.musclesListAdapteListener = musclesListAdapteListener;
   }

in your onbindviewholder change click listener

holder.muscleBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          musclesListAdapteListener.onClickItem();
        }
}

and your fragment must implement this interface

public class ExercisesFragment extends Fragment implements MusclesListAdapteListener {

  @Override
  void onClickItem() {
      //here your code to open fragment or what do you need
  }
}

also modify code where you create instance of adapter like this

ExercisesListAdapter adapter = new ExercisesListAdapter(this, exercisesList);
  • Related