0

I have a simple RecyclerView. that shows a bunch of images fetched from an API. but when I run the app the RecyclerView doesn't show any. when I debug it shows that my list is empty! I assume the issue relies on the loadimages function. but I have tried before with a simple TextView and it worked.I'm still new to this and I'm just practicing.

Main Activity:

public class MainActivity extends AppCompatActivity {

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

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    MallsAdapter adapter = new MallsAdapter(getApplicationContext());
    recyclerView.setAdapter(adapter);
}

Adapter Activity:

public class MallsAdapter extends RecyclerView.Adapter<MallsAdapter.MallsViewHolder> {

public static class MallsViewHolder extends RecyclerView.ViewHolder {
    public ImageView imageView;
    public LinearLayout containerView;

    public MallsViewHolder(@NonNull View itemView) {
        super(itemView);

        containerView = itemView.findViewById(R.id.pics_row);
        imageView = itemView.findViewById(R.id.flowers_pic);
    }
}

public List<Flowers> images = new ArrayList<>();
private static List<Drawable> drawables = new ArrayList<>();
private RequestQueue requestQueue;


public MallsAdapter(Context context) {
    requestQueue = Volley.newRequestQueue(context);
    loadImages();
}

@NonNull
@Override
public MallsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.malls_item, parent, false);
    return new MallsViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MallsViewHolder holder, int position) {
    holder.imageView.setBackground(drawables.get(position));
}

@Override
public int getItemCount() {
    if (images != null) {
        return images.size();
    } else {
        return 0;
    }
}

public static class DownloadImage extends AsyncTask<String, Void, Drawable> {
    @Override
    protected Drawable doInBackground(String... strings) {
        return downloadImage(strings[0]);
    }

    @Override
    protected void onPostExecute(Drawable drawable) {
        drawables.add(drawable);
    }

    private Drawable downloadImage(String urlLink) {
        URL url;
        InputStream in;
        BufferedInputStream buf;
        try {
            url = new URL(urlLink);
            in = url.openStream();
            buf = new BufferedInputStream(in);
            Bitmap bMap = BitmapFactory.decodeStream(buf);

            return new BitmapDrawable(bMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

private void loadImages() {
    String url = "https://pixabay.com/api/?key=15507399-305bf88eb0892f7cdf58fb66b&image_type=photo&pretty=true&q=yellow+flowers";
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                JSONArray hits = response.getJSONArray("hits");
                for (int i = 0; i < hits.length(); i++) {
                    JSONObject pics = hits.getJSONObject(i);
                    images.add(new Flowers(pics.getString("id"), pics.getString("largeImageURL")));
                }
                for (int i = 0; i < images.size(); i++) {
                    Flowers flowers = new Flowers(images.get(i).getId(), images.get(i).getImageURL());
                    new DownloadImage().execute(flowers.getImageURL());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("test", "Error", error);
        }
    });
    requestQueue.add(request);
}
2
  • you must pass ArrayList data through adapter Commented Mar 6, 2020 at 15:41
  • But I'm fetching the data within the adapter. I tried before using it without passing ArrayList to the adapter and it worked.
    – user7814219
    Commented Mar 6, 2020 at 15:43

1 Answer 1

1

2 things: first, the adapter shouldn't have any knowledge how your data is fetched, in fact it's not even its responsibility to do that job. In an MVVM architecture for example you'd have your activity calling the ViewModel, which in turn calls the repository to fetch the data, then, once the data is obtained, the activity passes it on to the adapter.

Second, and most important for your problem, when your adapter receives new data your adapter won't guess there's new stuff to render, so whenever there is new data it should call notifyDataSetChanged, which will in turn call getItemCount and onBindViewHolder to refresh your list.

Example:

// On your adapter
public void submitData(List<MyData> data) {
    this.data = data;
    notifyDataSetChanged();
}

@Override
public int getItemCount() {
    return data.size();
}
5
  • Fantastic explanation. that what I wanted to know, even tho I only read about MVVM once, and I'm a bit afraid to start implementing it. ill try to implement the repository and live-data-ViewModel. maybe will be fixed. plz if you have any other code tips regarding to mine. advise me. thank you so much
    – user7814219
    Commented Mar 6, 2020 at 16:33
  • Thank you! An app of mine uses MVVM, have a look at this class where I fetch the data and populate my RecyclerView. Hope it helps. github.com/alancamargo92/tweet-reader/blob/master/app/src/main/… PS.: Don't forget to accept the answer if it solved your problem
    – 92AlanC
    Commented Mar 6, 2020 at 16:41
  • I so wanted something similar to what u sent me. but in java I haven't coded in kotlen yet. I desperately need to learn how to implement MVVM with fetching the data. if u know any other resource but in java. I'd be hight appreciated.
    – user7814219
    Commented Mar 6, 2020 at 18:19
  • Check out this article: medium.com/upday-devs/… Please accept my answer to close the question if it solves your problem
    – 92AlanC
    Commented Mar 6, 2020 at 18:55
  • thank you. well, it didn't solve.still, data haven't been shown yet. ill try to use the MVVM and then see. i added the notifyDataSetChanged but still no data.
    – user7814219
    Commented Mar 6, 2020 at 21:16