The Only Smart Boy
The Only Smart Boy

Reputation: 575

Android Listview not showing items

I'm trying to add items to my list view dynamically from database using volley but it is not showing anything despite confirming that volley is actually returning the right items. My approach in achieving my desire was as bellow. I created an orders retriever as bellow:

      public class OrderRetriever {
private final Context d;
String user, token;
private OrderListViewAdapter orderAdapter;
final ArrayList<Order> myOrders = new ArrayList<>();

public OrderRetriever(Context d, String user, String token) {
    this.d = d;
    this.user = user;
    this.token = token;
}

public void retrieveOrder(final ListView listView, final KProgressHUD myProgressBar){
    myProgressBar.show();
    StringRequest serviceStringRequest = new StringRequest(Request.Method.POST, NetworkConstants.URL_MY_ORDERS,
            response -> {
                JSONObject jsonObject,photoObject;
                Order order;
                try{
                    JSONObject productObject = new JSONObject(response);
                    JSONArray productArray = productObject.getJSONArray("orders");
                    JSONArray photoArray = productObject.getJSONArray("photos");
                    if(productArray.length()>0){
                        String image = "", name, code,status;
                        int id;
                        double cost;
                        for(int i=0; i<productArray.length();i++){
                            jsonObject = productArray.getJSONObject(i);
                            id= jsonObject.getInt("id");
                            name = jsonObject.getString("name");
                            status = jsonObject.getString("status");
                            code = jsonObject.getString("code");
                            cost = jsonObject.getDouble("cost");
                            if(photoArray.length()>0){
                                for(int j=0; j<photoArray.length(); j++) {
                                    photoObject = photoArray.getJSONObject(j);
                                    if(photoObject.getInt("p_id")==jsonObject.getInt("id")) {
                                        image = photoObject.getString("path");
                                    }
                                }
                            }
                            order= new Order(name, status, code,NetworkConstants.URL_IMAGE +image,id,cost);
                            Log.d("Products", "retrieveFinalOrder: "+order);
                            myOrders.add(order);
                        }
                    }else{
                        myProgressBar.dismiss();
                        Toasty.warning(d,"No Orders found", 5000).show();
                    }
                    Log.d("TAG", "retrieveOrder: ");
                    orderAdapter = new OrderListViewAdapter(d,myOrders);
                    Log.d("TAG", "retrieveOrder: ading adapter");
                    listView.setAdapter(orderAdapter);
                    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();
                }
                Toast.makeText(d,"Error " + error, Toast.LENGTH_SHORT).show();

            }){
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            params.put("user",user);
            params.put("api_token", token);
            return params;
        }
    };
    serviceStringRequest.setRetryPolicy(new DefaultRetryPolicy(
            1000*5,
            /*DefaultRetryPolicy.DEFAULT_MAX_RETRIES*/ 3,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    RequestQueue productRequestQue = Volley.newRequestQueue(d);
    productRequestQue.add(serviceStringRequest);
}

}

This created the orders from the database using the orders model and passed them to the adapter as follows

      public class OrderListViewAdapter extends BaseAdapter {
Context c;
ArrayList<Order> orders;

public OrderListViewAdapter(Context c, ArrayList<Order> orders) {
    this.c = c;
    this.orders = orders;
}

@Override
public int getCount() {
    return orders.size();
}
@Override
public Object getItem(int position) {
    return orders.get(position);
}
@Override
public long getItemId(int position) {
    return position;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
    if(view==null){
        view = LayoutInflater.from(c).inflate(R.layout.order_list_layout,null,false);
    }
    TextView name = view.findViewById(R.id.name);
    TextView cost = view.findViewById(R.id.cost);
    TextView status = view.findViewById(R.id.status);
    ImageView image = view.findViewById(R.id.image);
    final Order order = (Order) this.getItem(position);
    name.setText(order.getName());
    cost.setText("KSH " + order.getCost());
    status.setText(order.getStatus());
    //check if there is an image returned
    if(order.getImage()!= null && order.getImage().length()>0){
        Picasso.with(c).load(order.getImage()).placeholder(R.drawable.drawerback).into(image);
    }else{
        Picasso.with(c).load(R.drawable.drawerback).into(image);
    }
    view.setOnClickListener(v -> {
        Intent intent = new Intent(c, ProductActivity.class);
        intent.putExtra("string_name","string_to_pass");
        c.startActivity(intent);
    });
    return view;
}

} This is how the order model looks

      public class Order {
private String name, status,code,image;
private int id;
double cost;

public Order(String name, String status, String code, String image, int id, double cost) {
    this.name = name;
    this.status = status;
    this.code = code;
    this.image = image;
    this.id = id;
    this.cost = cost;
}

Finally I called the retriever as follows in the ordersActivity

      container = findViewById(R.id.orderContainer);
        new OrderRetriever(this, clientid, new Db(this).getToken()).retrieveOrder(container,myProgressBar);

Despite all this and ensuring that the orders are available in response, nothing is shown What could I be missing or doing wrong?

Upvotes: 0

Views: 253

Answers (1)

ddassa
ddassa

Reputation: 309

There are few things i would change here,

  1. use a json parse like gson

  2. separate ui from network calls, do not mix ui components(listview, etc) with background task

  3. add a method as follows in OrderListViewAdapter

     public void setData(ArrayList<Order> orders) {
     this.orders.clear();this.orders.addAll(orders);
     notifyDataSetChanged();}
    
  4. In view, initialise adapter and set to list view as follows

     ListView lvOrders = findViewById(R.id.orderContainer);
     OrderListViewAdapter adapter = new OrderListViewAdapter(context, new ArrayList<>());
     lvOrders.setAdapter(adapter);
    
  5. retrieve your data in a background thread (use Thread, AsyncTask) and set the result to adapter in activity

     adapter.setData(resultFromApi);
    
  6. If its not too complex for you, try to use MVC,MVP, or MVVM pattern. It should work without any of these pattern, but always think ahead. makes it more easy to maintain in long run.

  7. Extra, always checks for null values

     @Override
     public int getCount() {
         return orders != null ? orders.size() : 0;
     }
     @Override
     public Object getItem(int position) {
         return orders != null ? orders.get(position) : null;
     }
    

Upvotes: 3

Related Questions