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