6

I have been reading the different answers here on stackoverflow and on this blog post and tried to implement their solutions but I am still getting the error:

RecyclerView﹕ No adapter attached; skipping layout

So I initialize my recycler view in onCreateView in my fragment like this:

public class ProfileFragment extends Fragment {

private ModelUser user;

private View view;
private RecyclerView gridView;
private ProfilePhotoRecyclerViewAdapter adapter;
private List<ModelAttachment> photoList = new ArrayList<ModelAttachment>();

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.fragment_profile, container, false);

    initializeRecyclerView();

    //Get extra info for user
    QueryAPI query = new QueryAPI();
    query.userExtra(user, new QueryAPI.ApiResponse<ModelUser>() {
        @Override
        public void onCompletion(ModelUser result) {
            user = result;
                photoList.clear();
                photoList.addAll(0,user.getPhotos());

                adapter.notifyDataSetChanged();

            }
        });

     return view;

}

}

The function initializeRecyclerView:

void initializeRecyclerView() {
        gridView = (RecyclerView) view.findViewById(R.id.grid_view);
        StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.HORIZONTAL );
        adapter = new ProfilePhotoRecyclerViewAdapter(getActivity(), photoList);
        gridView.setAdapter(adapter);
        gridView.setLayoutManager(gridLayoutManager);
        gridView.setHasFixedSize(true);
    }

The layout in the fragment:

 <android.support.v7.widget.RecyclerView
  android:id="@+id/grid_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"/>

And the layout of an item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/imageView"
    android:contentDescription="@string/image_description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:adjustViewBounds="true" />

 </LinearLayout>

What am I doing wrong?

EDIT: here is the adapter:

public class ProfilePhotoRecyclerViewAdapter extends  RecyclerView.Adapter<ProfilePhotoRecyclerViewAdapter.ViewHolder> {

    private LayoutInflater inflater;
    private List<ModelAttachment> photos; //data
    private Activity listContext;
    private int listRowLayoutId;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();


    public ProfilePhotoRecyclerViewAdapter(Activity context, List<ModelAttachment> objs) {
        photos = objs;
        listContext = context;
        this.notifyDataSetChanged();
    }

    @Override
    public ProfilePhotoRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {

        View itemView = LayoutInflater.from(listContext).inflate(R.layout.profile_photogrid_item, parent, false);

        return new ProfilePhotoRecyclerViewAdapter.ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ProfilePhotoRecyclerViewAdapter.ViewHolder viewHolder, int i) {

        ModelAttachment photo = photos.get(i);
        viewHolder.imageView.setImageUrl(photo.getUrl(), imageLoader);
    }

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


    public static class ViewHolder extends RecyclerView.ViewHolder {

        ModelAttachment photo;
        public NetworkImageView imageView;

        public ViewHolder(View itemView) {
            super(itemView);
            this.imageView = (NetworkImageView) itemView.findViewById(R.id.imageView);
        }
    }
}
Kalianey
  • 2,738
  • 6
  • 25
  • 43

3 Answers3

20

I never had this issue and it was really hard to replicate for me.

It is because you aren't setting empty adapter to RecyclerView first. The blog you give didn't exactly told how. Here is how I normally write.

My adapter constructor normally looks like this.

public ProfilePhotoRecyclerViewAdapter(Activity context) {
  photos = new ArrayList<>();
  listContext = context;
}

And write public (setter) method for the object array list.

public void setPhotos(List< ModelAttachment> photoList) {
  photos.clear();
  photos.addAll(photoList);
  this.notifyItemRangeInserted(0, photos.size() - 1);
}

And in your fragment, you don't have to initialise with photo array anymore.

adapter = new ProfilePhotoRecyclerViewAdapter(getActivity());

Just call the setter method from adapter inside your API response's onCompletion method.

@Override
public void onCompletion(ModelUser result) {
  photoList.clear();
  photoList.addAll(0,user.getPhotos());

  adapter.setPhotos(photoList);
}

I think this might solve. Feel free to ask and discuss.

Cheers,

SH

Swan
  • 886
  • 1
  • 9
  • 23
  • Thank you for the answer, unfortunately I tried and I still get the same error :/ – Kalianey Aug 19 '15 at 13:45
  • But now I tried by removing a scrollview I put around the whole fragment and it's working, I'm still having the error displayed in the log but I can see the images, I'm not sure why though... – Kalianey Aug 19 '15 at 14:05
  • Wait... So your problem wasn't only that error log? Can you please post the full code edit as I suggested? – Swan Aug 19 '15 at 15:29
  • @KaliAney Actually, I just fixed my two junior developers' code like this in the evening. The error log was because of recyclerview. They print out error log if there is empty adapter or data. – Swan Aug 19 '15 at 15:32
  • Great help. I was stuck in a same manner. This solved. Although it is a bit confusing "onCompletion()" so instead I used that code in "onActivityCompleted" – Suyash Dixit Dec 05 '15 at 05:12
  • 2
    @SH. Hello.What's the point of using `photos.clear(); photos.addAll(photoList);` instead of `photos = photoList` – Alexander Zar Feb 18 '16 at 14:36
  • @AlexanderZarovniy the easiest (dumbest) way to avoid List duplications? :D – Swan Feb 18 '16 at 15:08
  • @SH. I sorry If I'm asking dumb questions, but I feel really confused. `photos.clear()` removes everything(photos contains 0 elements now), then `photos.addAll(photoList)` adds each photoList element to photos.So photos is equal photolist now.That feels pretty much like `photos = photoList`. – Alexander Zar Feb 19 '16 at 07:41
  • @SH Don't you mean `photoList.removeAll(photos); photos.addAll(photoList); ` so you can call `notifyItemRangeInserted(photos.size(),photolistSize())`? – Alexander Zar Feb 19 '16 at 08:05
  • @Alexander Zarovniy I didn't mean your question as dumb question. My solution is the simplest one just for the demonstration purpose. In real world, there are conditions depend on your application needs. In my case, most of my apps don't clear the whole list first. They append to the list. :D – Swan Feb 19 '16 at 08:11
  • thanks, solved my problem too, instead of onCompletion i've used onActivityCreate method. – Biguá Mar 10 '17 at 20:49
  • I don't know how but it's worked for me god bless you. thank you so much – Vishal G. Gohel Jan 18 '18 at 09:42
1

make sure you have set LayoutManager to RecyclerView. Hope it will help :)

LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
Zubair Rehman
  • 2,335
  • 2
  • 20
  • 25
0

You're getting the error because you set the adapter when the data source (photoList) is still empty. and also saying to your recycler view that it's size will not change (by calling setHasFixedSize(true)) but you ARE changing the size of the list in the onCompletion callback of the query. So, remove setHasFixedSize(true) and it should work once you populate the list.

EDIT: I was wrong, the size in the method has nothing to do with data but with the size of the recycler view itself.

  • 2
    I have removed `setHasFixedSize(true) ` but it still gives me the same error :/ – Kalianey Aug 19 '15 at 07:29
  • Could you paste your adapter code as well? I take for granted that you are initializing the photoList somewhere before the callback? – m.stevanovic Aug 19 '15 at 07:38
  • 1
    This answer is wrong. `setHasFixedSize()` is talking about the view size of each row, not about the number of items the adapter has. [Please refer to the docs](http://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setHasFixedSize(boolean)) – Lawrence Choy Aug 19 '15 at 07:38
  • @m.stevanovic I have added the adapter code in my question. – Kalianey Aug 19 '15 at 07:48
  • Everything seems perfectly fine (except notifying the changes in the adapter constructor but I doubt that is the issue here). The only thing left to try is to recreate and [swap](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#swapAdapter(android.support.v7.widget.RecyclerView.Adapter,%20boolean)) the adapter in onCompletion callback and see what happens. – m.stevanovic Aug 19 '15 at 08:20
  • @lawrence-choy Thanks, TIL! – m.stevanovic Aug 19 '15 at 08:21
  • I've looked at `swap` but I don't really understand how to use it... Where should I put it in my code? – Kalianey Aug 19 '15 at 09:35