Prime47
Prime47

Reputation: 47

Android Custom ListView not building with Volley

I am parsing a JSON array from a public source and inserting them into a custom ListView. I have 4 classes;

  1. MySingleton for Volley Requests

    public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;
    
    private MySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
    
        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<String, Bitmap>(20);
    
                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }
    
                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }
    
    public static synchronized MySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new MySingleton(context);
        }
        return mInstance;
    }
    
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }
    
    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }
    
    public ImageLoader getImageLoader() {
        return mImageLoader;
    }}
    
  2. GameListItem

    public class GameListItem {

    private String itemName, itemLongDescription, itemShortDescription, itemReleaseDate;
    String releaseyear;
    private int iconID, imageID;
    
    public GameListItem(String itemName, String releaseyear, int iconID) {
    
        this.itemName = itemName;
        this.releaseyear = releaseyear;
        this.iconID = iconID;
    }
    
    public String getItemName() {
    
        return itemName;
    }
    
    public String getReleaseyear() {
        return releaseyear;
    }}
    
  3. CustomListAdapter

    public class CustomListAdapter extends BaseAdapter {

    private Context mContext;
    private LayoutInflater mInflater;
    private List<GameListItem> mDataSource;
    
    public CustomListAdapter(Context context, List<GameListItem> items) {
        mContext = context;
        mDataSource = items;
        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    
    
    @Override
    public int getCount() {
        return mDataSource.size();
    }
    
    @Override
    public Object getItem(int position) {
        return mDataSource.get(position);
    }
    
    @Override
    public long getItemId(int position) {
        return position;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = mInflater.inflate(R.layout.gamelist_layout, parent, false);
    
        TextView titleTextView = (TextView) rowView.findViewById(R.id.gameTitle);
    
        TextView subtitleTextView = (TextView) rowView.findViewById(R.id.gameDescription);
    
        titleTextView.setText(mDataSource.get(position).getItemName());
        subtitleTextView.setText(mDataSource.get(position).getReleaseyear());
    
        return rowView;
    }}
    
  4. MainActivity

    public class MainActivity extends AppCompatActivity {

    final String TAG = this.getClass().getSimpleName();
    RequestQueue requestQueue;
    private CustomListAdapter adapter;
    private List<GameListItem> gameList;
    private GameListItem gameItem;
    ListView listView;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Cache cache = new DiskBasedCache(getCacheDir(), 1024*1024);
        Network network = new BasicNetwork(new HurlStack());
        requestQueue = new RequestQueue(cache, network);
        requestQueue.start();
        listView = (ListView) findViewById(R.id.gameListView);
        gameList = new ArrayList<>();
    
        //This works and gives me a ListView with 5 rows
        gameList.add(new GameListItem("Test 1", "2019", R.mipmap.ic_launcher));
        gameList.add(new GameListItem("Test 2", "2092", R.mipmap.ic_launcher));
        gameList.add(new GameListItem("Test 3", "3243", R.mipmap.ic_launcher));
        gameList.add(new GameListItem("Test 4", "2323", R.mipmap.ic_launcher));
        gameList.add(new GameListItem("Test 5", "2123", R.mipmap.ic_launcher));
    
    
        //This doesn't work...
        String url = "http://api.androidhive.info/json/movies.json";
        JsonArrayRequest stringRequest = new JsonArrayRequest(url, new Response
                .Listener<JSONArray>(){
    
            @Override
            public void onResponse(JSONArray jsonArray) {
    
                if (jsonArray == null) {
                    Toast.makeText(MainActivity.this, "jsonArray is Null", Toast.LENGTH_LONG).show();
                } else {
                    try {
                        Toast.makeText(MainActivity.this, "ATTEMPTING PARSING", Toast.LENGTH_SHORT).show();
                        Log.e("This is the json array", jsonArray.toString());
    
                        for (int i = 0; i < jsonArray.length(); i++){
    
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            String title = jsonObject.getString("title");
                            int releaseYear = jsonObject.getInt("releaseYear");
    
                            gameList.add(new GameListItem(releaseDate, "" + releaseYear , R.mipmap.ic_launcher));
    
                            //this prints all the Titles and Release Dates correctly
                            Log.e("This is a title", title);
                            Log.e("This is a year", "HERE " + releaseYear);
    
    
    
                        }
    
                    } catch(JSONException e){
                        Log.i("JSON exception", e.toString());
                        Toast.makeText(MainActivity.this, "JSON ERROR", Toast.LENGTH_LONG).show();
                    }
    
                    requestQueue.stop();
                }
    
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
    
                Log.d("This is an error", ""+error.getMessage()+","+error.toString());
            }
        });
    
    
        MySingleton.getInstance(this).addToRequestQueue(stringRequest);
    
        adapter = new CustomListAdapter(this, gameList);
        listView.setAdapter(adapter);
    
    
    }}
    

As commented in main activity, when i manually add a row (with manual data) the ListView builds and displays, but the parser isn't showing anything. I checked countless of tutorials and everything seems in order, I even looked here and followed most of the answered I found yet nothing. Can someone see the bug causing the list not to build/print?

PS. the Log.e prints as well (which is inside the parser)

Thank you!

Upvotes: 1

Views: 405

Answers (2)

Evin1_
Evin1_

Reputation: 12866

Add the following line after your requestQueue.stop statement:

adapter.notifyDataSetChanged();

At first, when you set the adapter, the list has no data, because the Volley request will be made asynchronously, that's why you need to let the adapter know when its data has changed.

From the documentation:

notifyDataSetChanged()

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

Upvotes: 1

Abdullah Tellioglu
Abdullah Tellioglu

Reputation: 1474

If the request success, you must notify data change to adapter. In your case adapter.notifyDataSetChanged(); before catch block inside onResponse.

Upvotes: 1

Related Questions