'How to dynamically populate Spinner with text and image

I would like to dynamically populate my spinner with image and text but after numerous attempts, nothing is showing up, not even the log texts from the method for populateing the spinner. This is how I am calling the model to retrieve the category name and image

      public void setCategoryData(AllProductsActivity d, KProgressHUD myProgressBar) {
    Log.d("Products", "Data is being retrieved ");
    myProgressBar.show();
    StringRequest categoryStringRequest = new StringRequest(Request.Method.POST, NetworkConstants.URL_CATEGORY,
            response -> {
                Log.d("Products", "retrieveProductCategories: "+response);
                JSONObject jsonObject;
                Category category;
                try{
                    JSONObject categoryObject = new JSONObject(response);
                    JSONArray categoryArray = categoryObject.getJSONArray("categories");
                    if(categoryArray.length()>0){
                        String image = "", name, desc;
                        int id;
                        for(int i=0; i<categoryArray.length();i++){
                            jsonObject = categoryArray.getJSONObject(i);
                            id= jsonObject.getInt("id");
                            name = jsonObject.getString("name");
                            desc = jsonObject.getString("description");
                            image = jsonObject.getString("icon");
                            category= new Category(id, name, desc, NetworkConstants.URL_IMAGE +image);
                            CustomListViewValuesArr.add(category);
                        }
                    }else{
                        myProgressBar.dismiss();
                        Toasty.warning(d, "No Categories found", 5000).show();
                    }
                    myProgressBar.dismiss();
                }catch (JSONException e){
                    myProgressBar.dismiss();
                    e.printStackTrace();
                }
            },
            error -> {
                myProgressBar.dismiss();
                Log.d("Error", "Failed with error msg:\t" + error.getMessage());
                Log.d("Error", "Error StackTrace: \t" + Arrays.toString(error.getStackTrace()));
                // edited here
                try {
                    byte[] htmlBodyBytes = error.networkResponse.data;
                    Log.e("Error", new String(htmlBodyBytes), error);
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
                Toasty.error(d,"Error " + error, Config.SHORT_TOAST).show();
            }){
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            params.put("api_token", new Db(AllProductsActivity.this).getToken());
            return params;
        }
    };
    categoryStringRequest.setRetryPolicy(new DefaultRetryPolicy(
            1000*5,
            3,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    RequestQueue categoryRequestQue = Volley.newRequestQueue(d);
    categoryRequestQue.add(categoryStringRequest);
}

and this is how I am adding the adapter to the spinner and setting the onclick listener within the oncreate method of my activity class.

      // Set data in arraylist
    setCategoryData(this,myProgressBar);
    // Resources passed to adapter to get image
    Resources res = getResources();
    // Create custom adapter object ( see below CustomAdapter.java )
    adapter = new CategorySpinnerAdapter(this, R.layout.category_spinner_layout, CustomListViewValuesArr,res);
    // Set adapter to spinner
    categories.setAdapter(adapter);
    // Listener called when spinner item selected
    categories.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View v, int position, long id) {
            // Get selected row data to show on screen
            String Company    = ((TextView) v.findViewById(R.id.name)).getText().toString();

            String OutputMsg = "Selected category : \n\n"+Company+"\n"+id;

            Toast.makeText( AllProductsActivity.this,OutputMsg, Toast.LENGTH_LONG).show();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parentView) {
            // your code here
        }
    });

Just for clarity of what I have attempted to do, here is my adapter class

      public class CategorySpinnerAdapter extends ArrayAdapter<String> {

private final Activity activity;
private final ArrayList data;
public Resources res;
Category category =null;
LayoutInflater inflater;

/*************  CustomAdapter Constructor *****************/
public CategorySpinnerAdapter(
        AllProductsActivity activitySpinner,
        int textViewResourceId,
        ArrayList objects,
        Resources resLocal
)
{
    super(activitySpinner, textViewResourceId, objects);

    /********** Take passed values **********/
    activity = activitySpinner;
    data     = objects;
    res      = resLocal;
    /***********  Layout inflater to call external xml layout () **********************/
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getDropDownView(int position, View convertView,ViewGroup parent) {
    return getCustomView(position, convertView, parent);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return getCustomView(position, convertView, parent);
}

// This function called for each row ( Called data.size() times )
public View getCustomView(int position, View convertView, ViewGroup parent) {

    /********** Inflate spinner_rows.xml file for each row ( Defined below ) ************/
    View row = inflater.inflate(R.layout.category_spinner_layout, parent, false);

    /***** Get each Model object from Arraylist ********/
    category = (Category) data.get(position);
    TextView label = row.findViewById(R.id.name);
    CircleImageView companyLogo = row.findViewById(R.id.icon);

    if(position==0){
        // Default selected Spinner item
        label.setText("Category");
        Picasso.with(inflater.getContext()).load(R.drawable.loginbackground).into(companyLogo);
    }
    else
    {
        // Set values for spinner each row
        label.setText(category.getName());
        //check if there is an image returned
        if(category.getImage()!= null && category.getImage().length()>0){
            Picasso.with(inflater.getContext()).load(category.getImage()).placeholder(R.drawable.loginbackground).into(companyLogo);
        }else{
            Picasso.with(inflater.getContext()).load(R.drawable.loginbackground).into(companyLogo);
        }
    }
    return row;
}

}

After numerous struggles, I've gotten it to work but nothing happens when an item is selected, probably because the onItemSelected method is not being called. What could I be getting wrong?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source