Skip to content

create recycler view in fragment?

i want create a fragment and have inside a recycler view for show products …
but when i render it is show this error : RecyclerView: No adapter attached; skipping layout

below i copy my codes;

this code is for adapter class :

 private ArrayList<Products> ProductsList;
private Context context;

public Adapter(ArrayList<Products> productsList, Context context) {
    ProductsList = productsList;
    this.context = context;
}

@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
    return new MyHolder(v);
}

@Override
public void onBindViewHolder(MyHolder holder, final int position) {
    Products products = ProductsList.get(position);

    holder.txtName.setText(products.getName());
    holder.txtPrice.setText("$ " + products.getPrice());
    Picasso.get().load(Config.ipValue + "/images/" + products.getPhoto()).into(holder.imgV);
    holder.imgV.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.startAnimation(AnimationUtils.loadAnimation(context, android
                    .R.anim.slide_in_left));
        }
    });

}

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

class MyHolder extends RecyclerView.ViewHolder {

    TextView txtName;
    TextView txtPrice;
    ImageView imgV;

    public MyHolder(View itemView) {
        super(itemView);

        txtName = itemView.findViewById(R.id.rowTxtProductName);
        txtPrice = itemView.findViewById(R.id.rowTxtPrice);
        imgV = itemView.findViewById(R.id.rowImgProduct);
    }
}

and this one for web api class :

public class WebApiHandler {

Context context;
String apiLink = "";
ArrayList<Products> products = new ArrayList<>();

public WebApiHandler(Context context) {
    this.context = context;
}

void apiConnect(String type) {
    switch (type) {
        case "getproducts": {
            apiLink = Config.getProductsWebApi;
            break;
        }
    }

    ProgressDialog dialog = ProgressDialog.show(context, "Connecting...",
            "please wait", false, false);
    StringRequest request = new StringRequest(Request.Method.POST,
            apiLink, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            dialog.dismiss();
            showJson(response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            dialog.dismiss();
        }
    });
    RequestQueue queue = Volley.newRequestQueue(context);
    queue.add(request);
}

private void showJson(String response) {
    products.clear();
    try {
        JSONObject jsonObject = new JSONObject(response);
        JSONArray jsonArray = jsonObject.getJSONArray("response");
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            String id = object.getString("id");
            String name = object.getString("name");
            String description = object.getString("description");
            String price = object.getString("price");
            String photo = object.getString("photo");
            Products p = new Products(id, name, description, price, photo);
            products.add(p);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    VerticalFragment.productsArrayList = products;
    IData iData = (IData) context;
    iData.sendData();
}}

and my fragment code :

public class VerticalFragment extends Fragment implements IData {

RecyclerView rcVertical;
WebApiHandler webApiHandler;
static ArrayList<Products> productsArrayList = new ArrayList<>();

public VerticalFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_vertical, container, false);
    rcVertical = view.findViewById(R.id.rcVertical);
    webApiHandler = new WebApiHandler(getContext());
    webApiHandler.apiConnect("getproducts");
    rcVertical.addOnItemTouchListener(new RecyclerTouchListener(getContext(), rcVertical,
            new RecyclerTouchListener.ClickListener() {
                @Override
                public void onClick(View view, int position) {
                    ProductActivity.products = productsArrayList.get(position);
                    startActivity(new Intent(getContext(), ProductActivity.class));
                }

                @Override
                public void onLongClick(View view, int position) {

                }
            }));

    return view;
}

@Override
public void sendData() {
    Adapter adapter = new Adapter(productsArrayList, getContext());
    rcVertical.setLayoutManager(new LinearLayoutManager((getContext())));
    rcVertical.setItemAnimator(new DefaultItemAnimator());
    rcVertical.setAdapter(adapter);
}}

i should say i create a interface and have one method i say it sendData

Answer

This is a common error when there is no adapter attached to recyclerview upon showing recyclerview. It will not cause any harm to your app, but you could avoid it by setting empty adapter without data, and later when you get your data, provide it to your adapter and notify it

Edit – Example added

Create setter for your list in adapter. After that, in your fragment make adapter global and in onCreateView make instance of your adapter and attach it to recyclerview

adapter = new Adapter(new ArrayList<>(), getContext());
rcVertical.setAdapter(adapter);
...Initialize recyclerview...

And then in your sendData interface put your loaded values in it

adapter.setData(productsArrayList);
adapter.notifyDataSetChanged();