Can someone suggest me the best way to call a fragment function from the RecyclerView without causing any memmory leaks
My fragment code is given below
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.auth.AuthActivity">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/videoID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
app:resize_mode="fill"
app:controller_layout_id="@layout/player_control_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/materialList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/videoID">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
My recycler view layout is
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/_10sdp">
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:cardBackgroundColor="@color/circle_color_light"
app:layout_constraintVertical_bias="0.6">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
/>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
Please ignore any error on the above layouts since my issue lies on java code
My fragment code is given below
public class MaterialFragment extends DaggerFragment implements View.OnClickListener {
SimpleExoPlayer player;
PlayerView playerView;
@Inject
MaterialAdapter adapter;
@Inject
ViewModelProviderFactory providerFactory;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
makeVideo("https://samplevideo.com/test.mp4");
materialList = view.findViewById(R.id.materialList);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(),3,GridLayoutManager.VERTICAL,false);
materialList.setLayoutManager(gridLayoutManager);
materialList.setAdapter(adapter);
// The above code succesfully load the grid view using recycler adapter(Code for adapter is given below)
}
public void makeVideo(){
// Video loading code goes here : Loads video on findViewById(R.id.videoID)
}
}
Finally my Recycler Adapter view
public class MaterialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = "MaterialAdapter";
private List<Material> materials = new ArrayList<>();
private Context context;
public MaterialAdapter(){
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.material_grid_layout, parent, false);
PlayerView playerView = ((Activity)parent.getContext()).getWindow().getDecorView().findViewById(R.id.matVideo);
SimpleExoPlayer player = new SimpleExoPlayer.Builder(((Activity)parent.getContext()).getApplicationContext()).build();
context = parent.getContext();
return new MaterialAdapter.MaterialViewHolder(view,parent.getContext(),playerView,player);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
((MaterialAdapter.MaterialViewHolder)holder).bind(materials.get(position),context);
}
@Override
public int getItemCount() {
return materials.size();
}
public void setMaterials(List<Material> materials){
this.materials = materials;
notifyDataSetChanged();
}
public class MaterialViewHolder extends RecyclerView.ViewHolder {
TextView name,letter;
public Context cxt;
private SimpleExoPlayer player;
private PlayerView playerView;
public MaterialViewHolder(@NonNull View itemView, Context cxt, final PlayerView playerView, SimpleExoPlayer player) {
super(itemView);
this.cxt = cxt;
this.playerView = playerView;
this.player = player;
name = itemView.findViewById(R.id.name);
clayout = (ConstraintLayout) itemView.findViewById(R.id.card_layout);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// I need to change the video of the fragment on click of each block.
//The below code will work by implementing full makevideo function on this file
//But I need the bes method without repeting this function and call the methods of he fragment by passing video url or setting view contents of the outer fragment
//makeVideo("https://samplevideo.com/test.mp4"); // Not think this is he best solution as I need fullscreen function also.
// How to trigger button click of fragment, eg full screen
}
});
}
public void bind(Material material, Context context){
name.setText(material.getName());
}
}
}
Adapter is injected using module as given below
@Provides
static MaterialAdapter provideMaterialAdapter(){
return new MaterialAdapter();
}
After referring, I got some suggestion by using my own interface as a bridge between adapter and fragment , But It didn't work may be my dagger is causing some injection error,
Can someone give me a best solution to get rid of this issue
Use this adapter = new MaterialAdapter();
in your fragment rather than injecting it. Just remove the @Inject
annotation and add the above adapter creation statement in onViewCreated
of your fragment. By this way your get more control on your adapter creation and you can pass an interface through the constructor.