-2

Data is retrieving without any problem.But i want that data to be set to cardviews. When i try to execute below code, "Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference" in CustomAdapter class is the error i am facing. My code is

MainActivity.java

 public class MainActivity extends AppCompatActivity {
 RecyclerView recyclerView;
 CustomAdapter customAdapter;
 ArrayList<ProductsData> arrayList;
 ProgressDialog progressDialog;

String url = "url";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recyclerView);

    setUpRecycler();

    getData();
}

private void getData() {

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading...");
    progressDialog.show();

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            Log.d("result here","result here"+response);


            try {
                progressDialog.dismiss();

                JSONObject jsonObject = new JSONObject(response);

                arrayList = new ArrayList<>();
                JSONArray jsonArray = jsonObject.getJSONArray("products");
                for (int i = 0; i <= jsonArray.length();i++)
                {
                    ProductsData productsData = new ProductsData();
                    JSONObject obj = jsonArray.getJSONObject(i);

                    productsData.setProductImage(obj.getInt("image"));
                    productsData.setProductTitle(obj.getString("name"));
                    productsData.setProductPrice(obj.getString("price"));

                    arrayList.add(productsData);
                }

                setUpRecycler();

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(MainActivity.this, ""+error.toString(), Toast.LENGTH_SHORT).show();
        }
    }
    )
    {
        @Override
        public Map<String,String> getHeaders() throws AuthFailureError {
            Map<String,String>  params = new HashMap<>();
            params.put("Authorization", "1234567890");
            return params;
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

private void setUpRecycler() {
    recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),2));
    customAdapter = new CustomAdapter(this,arrayList);
    recyclerView.setAdapter(customAdapter);

}

}

CustomAdapter.java

 class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {

private Context context;
private ArrayList<ProductsData> arrayList;

public CustomAdapter(Context context, ArrayList<ProductsData> arrayList) {

    this.context= context;
    this.arrayList = arrayList;

}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

    View v  = LayoutInflater.from(context).inflate(R.layout.cardviewforproducts,viewGroup,false);
    MyViewHolder holder = new MyViewHolder(v);
    return holder;
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {

    myViewHolder.productImage.setImageResource(arrayList.get(i).getProductImage());
    myViewHolder.productName.setText(arrayList.get(i).getProductTitle());
    myViewHolder.productPrice.setText(arrayList.get(i).getProductPrice());

}

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

public class MyViewHolder extends RecyclerView.ViewHolder
{
    ImageView productImage;
    TextView productName;
    TextView productPrice;

    public MyViewHolder(@NonNull View itemView) {

        super(itemView);
        productImage = itemView.findViewById(R.id.productImage);
        productName = itemView.findViewById(R.id.productName);
        productPrice = itemView.findViewById(R.id.productPrice);

    }
}
}

ProductsData.java

public class ProductsData {

private int productImage;
private String productTitle,productPrice;


public int getProductImage() {
    return productImage;
}

public void setProductImage(int productImage) {
    this.productImage = productImage;
}

public String getProductTitle() {
    return productTitle;
}

public void setProductTitle(String productTitle) {
    this.productTitle = productTitle;
}

public String getProductPrice() {
    return productPrice;
}

public void setProductPrice(String productPrice) {
    this.productPrice = productPrice;
}
}

activitymain.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>

cardviewforproducts.xml

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

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:elevation="3dp"
    app:cardElevation="4dp"
    app:cardCornerRadius="1dp"
    app:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp">

        <ImageView
            android:id="@+id/productImage"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            />

        <TextView
            android:id="@+id/productName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Apple MacBook Air Core i5 5th Gen - (8 GB/128 GB 
  SSD/Mac OS Sierra)"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/productPrice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:textStyle="bold" />

    </LinearLayout>

</android.support.v7.widget.CardView>

</LinearLayout>

I expect that retrieved products should set to cardviews.

But the error am facing is Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference

Eswar
  • 199
  • 1
  • 13
  • remove `setUpRecycler();` from onCreate() and Try. – Chirag Savsani Jun 11 '19 at 12:20
  • yeah ,i tried but now my activity is blank and the error is **No adapter attached; skipping layout** – Eswar Jun 11 '19 at 12:23
  • check what is the size of arraylist in MainActivity – USER9561 Jun 11 '19 at 12:24
  • Check that your `arrayList` in getData() method is null or not before call `setUpRecycler();` – Chirag Savsani Jun 11 '19 at 12:24
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – ADM Jun 11 '19 at 12:25
  • So issue may be related to Data. Your arraylist might be empty. – Chirag Savsani Jun 11 '19 at 12:25
  • Make sure that you not get any Json Exception. Because you are creating new ArayList after Json. – Tariqul Islam Jun 11 '19 at 12:27
  • After retrieving data, logcat displays below error 2019-06-11 18:04:06.979 27186-27186/com.example.practive I/System.out: Size of array is5 2019-06-11 18:04:06.980 27186-27186/com.example.practive W/System.err: org.json.JSONException: Index 5 out of range [0..5) 2019-06-11 18:04:06.981 27186-27186/com.example.practive W/System.err: at com.example.practive.MainActivity$1.onResponse(MainActivity.java:73) 2019-06-11 18:04:06.981 27186-27186/com.example.practive W/System.err: at com.example.practive.MainActivity$1.onResponse(MainActivity.java:56)' – Eswar Jun 11 '19 at 12:39

3 Answers3

0

You need to initialize you array list globally

ArrayList<ProductsData> arrayList = new ArrayList<>();
Hitesh Kushwah
  • 1,351
  • 13
  • 23
  • I've changed my code and initialized as you said, i am facing **No Adapter attached;skipping Layout** error – Eswar Jun 11 '19 at 12:46
  • you need to initialize it in activity because in oncreate method you are calling setupRecycler() method thats why it give error – Hitesh Kushwah Jun 11 '19 at 12:48
  • so when your activity first time run arrylist is that time get null, you initialize your arrayList at the time your response comes so you need to initialize it globally its defiantly solve your prob – Hitesh Kushwah Jun 11 '19 at 12:49
  • Yeah, i've initialized it in activity itself. also i've removed setupRecycler() from onCreate(), Still i am facing the same issue. – Eswar Jun 11 '19 at 12:51
  • ok in oncreate method you call your setupRecycler() method and remove from getdata() method and add customeAdapter.notifyDataSetChanged(); in getdata() method in place of setupRecycler() ok Try this – Hitesh Kushwah Jun 11 '19 at 12:56
0

Remove setUpRecycler(); from the OnCreate()

So your onCreate() will look like below

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recyclerView);
    getData();
}

Issue arise because, you are initialize arraylist in getData() and call setUpRecycler() before getData(), so at that time arraylist not initialized.

Chirag Savsani
  • 6,020
  • 4
  • 38
  • 74
  • yeah ,i've removed it from onCreate(), but now my activity is blank and the error is No adapter attached; skipping layout – Eswar Jun 11 '19 at 12:44
0

You need to have notifyDataSetChanged inside getData() method to your customAdapter. Because you are setting up null adapter in setUpRecycler() so you need to have call that.

Modify your getData() method as below. You not need to have call setUpRecycler() again inside that method.

Also move this arrayList = new ArrayList<>(); inside setUpRecycler() as this need to be called only once.

private void getData() {

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading...");
    progressDialog.show();

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            Log.d("result here","result here"+response);


            try {
                progressDialog.dismiss();

                JSONObject jsonObject = new JSONObject(response);

                JSONArray jsonArray = jsonObject.getJSONArray("products");
                for (int i = 0; i <= jsonArray.length();i++)
                {
                    ProductsData productsData = new ProductsData();
                    JSONObject obj = jsonArray.getJSONObject(i);

                    productsData.setProductImage(obj.getInt("image"));
                    productsData.setProductTitle(obj.getString("name"));
                    productsData.setProductPrice(obj.getString("price"));

                    arrayList.add(productsData);
                }

                customAdapter.notifyDataSetChanged();

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(MainActivity.this, ""+error.toString(), Toast.LENGTH_SHORT).show();
        }
    }
    )
    {
        @Override
        public Map<String,String> getHeaders() throws AuthFailureError {
            Map<String,String>  params = new HashMap<>();
            params.put("Authorization", "1234567890");
            return params;
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

Also modify your setUpRecycler() method as this.

private void setUpRecycler() {
    arrayList = new ArrayList<>();
    recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),2));
    recyclerView.setHasFixedSize(true);
    customAdapter = new CustomAdapter(this,arrayList);
    recyclerView.setAdapter(customAdapter);

}
Jay Rathod
  • 11,131
  • 6
  • 34
  • 58
  • Yeah bro, i tried as you said, but the error still exist - **No Adapter attached;skipping Layout** – Eswar Jun 11 '19 at 12:57
  • Did you moved *arrayList = new ArrayList<>();* from *getData()* to *setUpRecycler()* method as stated in my answer ? – Jay Rathod Jun 11 '19 at 13:00
  • also - i've moved arraylist initialization in setupRecycler() , still the error exist and app crashes – Eswar Jun 11 '19 at 13:00
  • Did you checked *arrayList.size()* make sure it adds data into it. Print it's size *arrayList.size()* once and check. mostly it will work.. Also update your question with code you changed.. Make sure your *arrayList* is not empty.. – Jay Rathod Jun 11 '19 at 13:03
  • @Eswar Check my updated answer modify your *setUpRecycler()* method as that and check. Also remove *recyclerView = findViewById(R.id.recyclerView);* from *onCreate* method because it defined in *setUpRecycler()* method. – Jay Rathod Jun 11 '19 at 14:00
  • Thanks bro, Your setUpRecycler() worked like a charm. But we need to call it before try block in getData(). Then it is working without any issues. Anyway - **No Adapter attached;Skipping layout** is the issue still exist in Logcat, Ignoring it. Once again thanks buddy. – Eswar Jun 12 '19 at 04:43