Kodeco Forums

Android RecyclerView Tutorial

Learn how to display datasets of large or unknown size in this Android RecyclerView tutorial!


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1092-android-recyclerview-tutorial

where did you get receivedNewPhoto()??? Does this guide need an update? I am very confused there are a few issues where you ask to write code but the guide nor the studio give/create those areas. Maybe I am missing something.

receivedNewPhoto() is included in MainActivity of the starter code.

None of the images are coming down from the API. The date and description works fine but for some reason the photos will not. The photos don’t load in the final version either, I downloaded and ran it just to be safe.

The api returns the following :
{
“date”: “2016-12-31”,
“explanation”: “The Trifid Nebula, also known as Messier 20, is easy to find with a small telescope, a well known stop in the nebula rich constellation Sagittarius. But where visible light pictures show the nebula divided into three parts by dark, obscuring dust lanes, this penetrating infrared image reveals filaments of glowing dust clouds and newborn stars. The spectacular false-color view is courtesy of the Spitzer Space Telescope. Astronomers have used the Spitzer infrared image data to count newborn and embryonic stars which otherwise can lie hidden in the natal dust and gas clouds of this intriguing stellar nursery. As seen here, the Trifid is about 30 light-years across and lies only 5,500 light-years away. News: Leap second to be added to 2016.”,
“hdurl”: “http://apod.nasa.gov/apod/image/1612/trifid_spitzerR.jpg”,
“media_type”: “image”,
“service_version”: “v1”,
“title”: “Infrared Trifid”,
“url”: “http://apod.nasa.gov/apod/image/1612/trifid_spitzerR1024.jpg
}
Picasso should be able to download using url in the json; However I confirm ,as is,it does not work for me either. Have to dissect the code .

I had to modify getUrl() to include return “https://apod.nasa.gov/apod/image/1612/trifid_spitzerR1024.jpg” before it would work.

@mademma but…it does that already ?..in Photo… public String getUrl() {
return mUrl;
}

only issue I could see is the media_type should be image not video, however that is still not working,
but did yours work?

I didn’t explain it very good. mUrl returns http://apod.nasa.gov/apod/image/1612/trifid_spitzerR1024.jpg" before it would work. I modified mUrl to contain https://apod.nasa.gov/apod/image/1612/trifid_spitzerR1024.jpg" before turning it. (added the “s”).

Also, I did change the media_type to image.

I also changed ImageRequester onResponce as follows:

From: if (!photoJSON.getString(MEDIA_TYPE_KEY).equals(MEDIA_TYPE_VIDEO_VALUE)) {
To: if (photoJSON.getString(MEDIA_TYPE_KEY).equals(MEDIA_TYPE_VIDEO_VALUE)) {

I haven’t had a chance to really look into that change and why it worked.

@mademma Thanks , yeah it works now,kind of, also I removed the date qualifier in the url with the api key…it was not liking the new year…:sunglasses:

Hi, everyone.

You can simply change one line.

in Photo.java line 46 :

mUrl = photoJSON.getString("url");

To.

mUrl = photoJSON.getString("url").replace("http://", "https://");

Happy new Year. :gift:

1 Like

Thanks, Great Tutorial !

Hi, I’m getting a Null Pointer Exception. Did I miss something?

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference at com.raywenderlich.galacticon.RecyclerAdapter.getItemCount(RecyclerAdapter.java:82)

Thanks for the help and the tutorial.

I got this too. It’s because I forgot to implement the constructor for mPhotos in the RecyclerAdapter.

At the top of your RecyclerAdapter class, add a variable to hold your photos:

private ArrayList<Photo> mPhotos;

Next, add a constructor to set it up:

    public RecyclerAdapter(ArrayList<Photo> photos) {
        mPhotos = photos;
    }

Thanks for your answer. I checked it but variable and constructor is set just like in the tutorial.

This is the full log message:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.raywenderlich.galacticon, PID: 11787
java.lang.NullPointerException: Attempt to invoke virtual method ‘int java.util.ArrayList.size()’ on a null object reference
at com.raywenderlich.galacticon.RecyclerAdapter.getItemCount(RecyclerAdapter.java:82)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:2938)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2904)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1730)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1496)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:435)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:726)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
E/EGL_emulation: tid 11809: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x7a5c6180da00, error=EGL_BAD_MATCH
Application terminated.

I’m pretty much new to Android so I appreciate the help!

The null pointer exception is likely caused by the code being in the wrong order:

Next, underneath the creation of your array list in onCreate() add the following:
mAdapter = new RecyclerAdapter(mPhotosList);
mRecyclerView.setAdapter(mAdapter);

Make sure the order is correct - you must do the mAdapter work after the ArrayList otherwise you get that exception:

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

    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    mLinearLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLinearLayoutManager);

    //These two lines first - they are in the starter project
    mPhotosList = new ArrayList<>();
    mImageRequester = new ImageRequester(this);

    //These two lines you must add as per description - after ArrayList
    mAdapter = new RecyclerAdapter(mPhotosList);
    mRecyclerView.setAdapter(mAdapter);
  }

One other thing to note - NASA works to an American time zone (not exactly sure which one). This means that you may get an exception when asking for the API if the picture has not yet been published but your timezone is already moved to the next day - for example its 2nd March in UK but still 1st March in USA.

Under these circumstances the app will show in the android debugger (at start of a stacktrace):
W/System.err: org.json.JSONException: No value for media_type

The JSON returned is:
{ "code": 500, "msg": "Internal Service Error", "service_version": "v1" }

If you have not yet implemented the scrolling code yet you will not see any photo although the app is technically operating correctly.

I have couple of question, could you please answer me?

  1. How can I create a layout which contains both imageview and textview separately? For example say having an items conatining 12 items with 6 images and 6 texts

  2. Can we have non-scrollable listview or gridview? I want the screen to be non scrollable and the list of items should fit the screen size.

Hi, first sorry for my english bro haha
i am a bit confused about how you save the photo object. Do you save it in ArrayList or something else, it’s really help if you can show me where the code to save the Photo Object. Thanks guys. And once again sorry for my english :slight_smile:

I will show you how we can use a real-time database of google FireBase and map data with RecyclerView and cardView in Android.after connecting firebase database with the android studio. create RecyclerViewAdapter and pass the JSON of the firebase to the RecyclerViewAdapter.
http://www.programmingviral.com/android/firebase-recyclerview-tutorial/

This tutorial is more than six months old, so questions are no longer supported at the moment for it. We will update it as soon as possible. Thank you! :]