'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 |
|---|
