Home > front end >  You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null. A
You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null. A

Time:09-24

Im using Room DataBase, and im trying to paste an image in a RecyclerView. But when im trying to retrieve data to adapter class, then im get
You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed). In other topics i saw about isAdded() methods, but i cant use that in Adapter class

This is my clickListener from parentClass

        ARB.contRem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(ARB.remText.getText().toString().equals("")){
                    ARB.err.setText("errCode");
                }
                else if(ARB.dateFromCalendar.getText().toString().equals("")){
                    ARB.err.setText("errCode");
                }
                else {

                    Bitmap bitmap = ((BitmapDrawable)ARB.addImageRem.getDrawable()).getBitmap();
                    Uri uri = getImageUri(getContext(), bitmap);

                    ARVM.addReminder(ARB.remText.getText().toString(),
                            ARB.dateFromCalendar.getText().toString(),
                            false,
                            uri.toString());

                    Navigation.findNavController(v).popBackStack();
                }
            }
        });

This is from AdapterClass

@Override
    public void onBindViewHolder(@NonNull reminderViewHolder holder, int position) {

        Uri uri = Uri.parse(rems.get(position).getImages());



        Glide.with(ct).load(new File(uri.getPath())).into(holder.binding.imageView);

        holder.binding.textrow.setText(rems.get(position).getTextRem());
        holder.binding.daterow.setText(rems.get(position).getDateRem());
        holder.binding.isdone.setChecked(rems.get(position).isDone());

    }

Thats what im get after trying to retrieve data

2021-09-23 15:28:10.308 5391-5391/com.example.rempractice E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.rempractice, PID: 5391
    java.lang.NullPointerException: You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).
        at com.bumptech.glide.util.Preconditions.checkNotNull(Preconditions.java:29)
        at com.bumptech.glide.Glide.getRetriever(Glide.java:769)
        at com.bumptech.glide.Glide.with(Glide.java:801)
        at com.example.rempractice.project.View.adapters.reminderAdapter.onBindViewHolder(reminderAdapter.java:40)
        at com.example.rempractice.project.View.adapters.reminderAdapter.onBindViewHolder(reminderAdapter.java:19)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:784)
        at android.view.View.layout(View.java:22844)
2021-09-23 15:28:10.308 5391-5391/com.example.rempractice E/AndroidRuntime:     at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3470)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2938)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

CodePudding user response:

I'm in this cases usually pass a reference to the host fragment or its context to the adapter constructor to keep it and use it when it needs to in Glide like this :

public class MyAdapter extends RecyclerView.Adapter<reminderViewHolder > {
    private final Fragment hostFragment;
    public MyAdapter (Fragment m_hostFragment) {
            this.hostFragment = m_hostFragment;
    }

    ...

    public void onBindViewHolder(@NonNull reminderViewHolder holder, int position) {
            Uri uri = Uri.parse(rems.get(position).getImages());
            Glide.with(hostFragment).load( uri).into(holder.binding.imageView);
    }

}

and when I initialize my adapter in my fragment I would just pass my fragment reference

public class MyFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@Nullable  Bundle savedInstanceState) {
       ...
       MyAdapter pagesAdapter = new MyAdapter (this);
       ...
    }
    ...
}

Update to what we're talking about in comments

it depends on what you're returning from the getImages method. I don't know what are you returning there, but you should be returning only one string that belong to only one image at a time.

RecyclerView is a list with each row/column representing a different holder, for each holder RecyclerView calls onBindHolder to initialize it, if you want to show multiple images you should show each one in a different holder and RecyclerView will call onBindHolder multiple times until all your arraylist data's is on the screen.

so as an assumption if your data ArrayList if of type string where each item holds one image uri string, then it's enough to get the uri string in one onBindViewHolder.

public class MyAdapter extends RecyclerView.Adapter<reminderViewHolder>{
    private final Fragment hostFragment;
    List<String> photos ; 
    public MyAdapter (Fragment m_hostFragment,List<String> photos) {
            this.hostFragment = m_hostFragment;
            this.photos = photos;
    }

    ...

    public void onBindViewHolder(@NonNull reminderViewHolder holder, int position) {
            String photo_Uri = photos.get(position);
            Glide.with(hostFragment).load(photo_Uri).into(holder.binding.imageView);
    }

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

and your RecyclerView will call onBindViewHolder as many times as getItemCount returns to represent all your data.

  • Related