2

I have been reading different answers here on stackoverflow and i tried to implement the solution but I am still getting the same error, I don't know why ! :/

This is my Adapter Class :

public class RecipesAdapter extends RecyclerView.Adapter <RecipesAdapter.RecipeHolder>{

private List<Recipes> recipesList;
private static Recipes recipe;
private static Intent intent;
private Context context;
private View row;
private RecipeHolder holder;

//Conctructor
public RecipesAdapter(List<Recipes> recipesList)
{
    this.recipesList=recipesList;
}

//create holder (view)
@Override
public RecipeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     row= LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_row, parent,false);
    //Call constructor : Holder
     holder=new RecipeHolder(row);
    return holder;
}

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

    recipe= recipesList.get(position);

    holder.recipe_title.setText(recipe.getTitle());
    Picasso.with(holder.recipe_image.getContext()).load(recipe.getImage_url()).into(holder.recipe_image);
    holder.recipe_rank.setText(recipe.getSocial_rank().split("\\.",2)[0]);
    holder.recipe_publisher.setText(recipe.getPublisher());
}

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

/*To avoid calling methods findViewById for each view, Android has added a concept called ViewHolder
 to change 'the values' of each View => concept of Recycling */
public class RecipeHolder extends RecyclerView.ViewHolder
{

    private ImageView recipe_image;
    private TextView recipe_title,recipe_rank,recipe_publisher;

    public RecipeHolder(View itemView) {
        super(itemView);
        recipe_image=(ImageView) itemView.findViewById(R.id.recipe_img);
        recipe_title=(TextView) itemView.findViewById(R.id.recipe_title);
        recipe_rank=(TextView) itemView.findViewById(R.id.recipe_rank);
        recipe_publisher=(TextView) itemView.findViewById(R.id.recipe_publisher);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 context = v.getContext();
                 intent = new Intent(context, DetailRecipe.class);
                intent.putExtra("url",recipesList.get(getAdapterPosition()).getF2f_url());
                intent.putExtra("image",recipesList.get(getAdapterPosition()).getImage_url());
                Log.e("log","url is : "+recipe.getF2f_url());
                context.startActivity(intent);
            }});
    }
}
}

onCreate Method

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cookingrecipes); // Adding Toolbar to Main screen toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); Connection_GetData(); }

onResponse Method : when the connection was successful

I used Retrofit library to get data, I called Display_Recipes() to set Adapter

        `@Override
        public void onResponse(Call<ResultRecipes> call, Response<ResultRecipes> response) {

            recipesList = response.body().getRecipes();
                //Recycler View
                recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
                recyclerView.setHasFixedSize(true);
                /*Performance*/
                recyclerView.setItemViewCacheSize(24);
                recyclerView.setDrawingCacheEnabled(true);
                recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

                recyclerView.setLayoutManager(new GridLayoutManager(CookingRecipes.this, 2));

            /*Treatment - Display*/
                Display_Recipes();
            }`

Display_Recipes() Method

`public void Display_Recipes() {
    //Setup Adapter
    this.recipeAdapter = new RecipesAdapter(recipesList);
    recyclerView.setAdapter(recipeAdapter);
}`

Image Log Many Thanks,

iLyas
  • 1,047
  • 2
  • 13
  • 30
  • Do you get the same log after you call `Display_Recipes()`? – Abbas Oct 05 '16 at 10:07
  • please check answer for http://stackoverflow.com/questions/29141729/recyclerview-no-adapter-attached-skipping-layout , if you not setting adapter from your main thread then it will cause this error – Sanjeet Oct 05 '16 at 10:50
  • @Abbas : No, without calling Display_Recipes() method I get the warning. – iLyas Oct 05 '16 at 11:43
  • @iLyasDev The simple issue that you are facing is that your Adapter is never attached to the `RecyclerView` but it is shown in the view. I haven't found this warning to be fatal in any case, but if you want it gone then simply add the `Adapter` for the `RecyclerView` in your `onCreate()` method (or wherever you are creating `RecyclerView`) and finally add/update the `Adapter`'list later in `Display_Recipies()`. – Abbas Oct 05 '16 at 13:07
  • @Abbas : Look at my solution below – iLyas Oct 06 '16 at 10:53

4 Answers4

4

It's necessary to set LayoutManager on main thread instead of calling inside any callback.

Update your onCreate method as per below :

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cookingrecipes);
        // Adding Toolbar to Main screen
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        //Shifted your recycler view code here

       //Recycler View
       recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
       recyclerView.setHasFixedSize(true);
       /*Performance*/
       recyclerView.setItemViewCacheSize(24);
       recyclerView.setDrawingCacheEnabled(true);
       recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

       recyclerView.setLayoutManager(new GridLayoutManager(CookingRecipes.this, 2));

       // Only pass context to your adapter
       recyclerView.setAdapter(new RecipesAdapter(CookingRecipes.this);

        Connection_GetData();
    }

And update your onResponse Callback :

 @Override
 public void onResponse(Call<ResultRecipes> call, Response<ResultRecipes> response) {

         recipesList = response.body().getRecipes();

         /*Treatment - Display*/
         Display_Recipes();
  }

Create method to update list in your adapter whenever you need to pass updated list :

public void udpateList(List<Recipes> recipesList){
    this.recipesList = recipesList;
    notifyDataSetChanged();
}

Now call this method from your Display_Recipes method

public void Display_Recipes() {
        //Update Adapter
        udpateList(recipesList);
    }
Jai
  • 1,974
  • 2
  • 22
  • 42
  • 1
    Thank you for helping, but the same result **E/RecyclerView: No adapter attached; skipping layout**, i don't know because what ! – iLyas Oct 05 '16 at 10:22
  • @iLyasDev : Are you setting adapter only one time or multiple time from any other place in your code? – Jai Oct 05 '16 at 10:26
  • @iLyasDev : Check my updated answer and try to set layoutManger simply without setting anything related to ItemViewCacheSize. Try it and let me know – Jai Oct 05 '16 at 10:30
  • i'm setting adapter only one time, but I was discovered the problem, my code is correct but when i try to debug my application on the API 10, I get the warning **E/RecyclerView: No adapter attached; skipping layout**, I think all API below 11 they will have the same warning – iLyas Oct 05 '16 at 10:38
  • in any case, i don't think it's necessary to set LayoutManager on main thread, it's optional. – iLyas Oct 05 '16 at 10:49
  • @iLyasDev : You are using recyclerview widget which is included in v7 support library so you have support till API level 7. So something is wrong its not about below api level 11 will get this error – Jai Oct 05 '16 at 10:52
  • yes as you said, i used v7 support library, API => min : 10 & max : 24 – iLyas Oct 05 '16 at 11:02
  • @iLyasDev : I updated my code again, you could try that way before setting empty adapter and then update it using notifydatasetchanged() – Jai Oct 05 '16 at 11:11
  • I used your update code, but I got the same warning in the API 10 – iLyas Oct 05 '16 at 11:28
  • like this ? public void Display_Recipes() { recipeAdapter = new RecipesAdapter(recipesList); recyclerView.setAdapter(recipeAdapter); //Update Adapter recipeAdapter.UpdateList(recipesList); } and : public RecipesAdapter(Context context) { this.context=context; } – iLyas Oct 05 '16 at 13:44
  • Look at my solution – iLyas Oct 06 '16 at 10:53
  • @iLyasDev : That's what I did already dude :) Check my code properly. I set adapter first and then I updated it using updateList method – Jai Oct 06 '16 at 10:56
  • @iLyasDev : Ultimate solution was you have to set layoutmanager on main thread. – Jai Oct 06 '16 at 10:57
  • You are right, I already understood what you mean, in any case Thank you very much. – iLyas Oct 06 '16 at 11:50
1

Thank you all my friends, I was discovered the error, the code is correct but to avoid this warning, we need to set an empty adapter in onCreate method. After inside the method that you want to get the data, in my case with Retrofit library : Connection_GetData();

1 - create class Adapter like that

public class AdapterFirstUse extends RecyclerView.Adapter {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

}

@Override
public int getItemCount() {
    return 0;
}

}

2 - Inside onCreate(Bundle savedInstanceState) method

recyclerView.setAdapter(new AdapterFirstUse());

3 - Inside Connection_GetData()

Setup our Adapter

  //Setup Adapter
   recipeAdapter = new RecipesAdapter(recipesList);
   recyclerView.setAdapter(recipeAdapter);

That's all, Thanks.

iLyas
  • 1,047
  • 2
  • 13
  • 30
  • You are using recyclerview widget which is included in v7 support library so you have support till API level 7. So something is wrong its not about below api level 11 will get this error – Jai Oct 05 '16 at 10:56
  • Yes, as you said, i used v7 support library, API => min : 10 and max : 24 when i debug on api 10 I get the warning but for others it's fine – iLyas Oct 05 '16 at 11:00
  • the meaning of v7 support library = Support till API level 7 – Jai Oct 05 '16 at 11:10
0

The problem might be the adapter is not telling the RecyclerView to update its content.

Add a method in your RecipeAdapter:

public void refresh() {
   notifyDataSetChanged();
}

Then call it after binding the adapter to the RecyclerView;

recyclerView.setAdapter(recipeAdapter);
recipeAdapter.update();
fillobotto
  • 3,698
  • 5
  • 34
  • 58
  • Thanks @fillobotto, I was discovered the problem, my code is correct but when i try to debug my application on the API 10, I get the warning **E/RecyclerView: No adapter attached; skipping layout**, I think all API below 11 they will have the same warning – iLyas Oct 05 '16 at 10:37
  • I tested what you said, but i get the same error on the API 10 – iLyas Oct 05 '16 at 10:54
0

Mine was solved by inputting an empty list data first upon initialisation of the adapter, and update data later, example:

initialise adapter in onCreate():

onCreate() {

...
initRecyclerView();
...

}

initRecyclerView() :

public void initRecyclerView() {

            //setup recyclerview
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            recyclerView.setHasFixedSize(true);
            /*Performance*/
            recyclerView.setItemViewCacheSize(24);
            recyclerView.setDrawingCacheEnabled(true);
            recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

            recyclerView.setLayoutManager(new GridLayoutManager(CookingRecipes.this, 2));

    //Setup Adapter
    this.recipeAdapter = new RecipesAdapter(new List());//try to set an empty adapter here first
    recyclerView.setAdapter(recipeAdapter);
}

then inside onResponse:

@Override
public void onResponse(Call<ResultRecipes> call, Response<ResultRecipes> response) {

     //only do data update inside onResponse
     recipesList = response.body().getRecipes();
     recipeAdapter.recipesList = recipesList;
     notifyDataSetChanged();

}
Beeing Jk
  • 3,796
  • 1
  • 18
  • 29