5

I'm relatively new to Java programming and I'm working on an assignment from the Android Basics Nanodegree program (Udacity). I'm building a custom class (Song) and populating a layout using an ArrayAdapter and a RecyclerView. I've imported ButterKnife for binding the data.

The data for the array has been hard-coded into a typed array resource in strings.xml. There is one typed array for each attribute of the song - song title, album title, artist name, song length, and cover art. All are Strings except for cover art which is an int (Drawable Resource ID). When I run the app, all data points are populated into the layout (RecyclerView) except for the cover art.

I've tried several iterations of defining the typed array, but each time the value that gets brought into the array when I run the app is "0" for each cover art. I've tried coding the typed array as <array name="songsCoverArt"> ...</array> and also tried <integer-array name="songsCoverArt">...</integer-array>. Exact same result each time.

The array is populated in the MainActivity.java.

ArrayList<Song> songs = new ArrayList<>();
    String[] songTitle = getResources().getStringArray(R.array.songsTitles);
    String[] albumTitle = getResources().getStringArray(R.array.albumTitle);
    String[] songLength = getResources().getStringArray(R.array.songsLength);
    String[] artistName = getResources().getStringArray(R.array.artistName);
    int[] songCoverArt = getResources().getIntArray(R.array.songsCoverArt);

    for (int i = 0; i < songTitle.length; i++) {
        // debug logging
        Log.d(TAG, "Adding = " + songTitle[i] + " " + albumTitle[i] + " " + songLength[i] + " " + artistName[i] + " " + songCoverArt[i]);
        songs.add(new Song(songTitle[i], albumTitle[i], songLength[i], artistName[i], songCoverArt[i]));
     }
     songAdapter.addItems(songs);
     recyclerView.setAdapter(songAdapter);

The typed array for the cover art in the strings.xml and looks like this:

<array name="songsCoverArt">
   <item>@drawable/coverart_indigo_big</item>
   ...
</array>

I've also tried defining the Drawables like this, which gives me the exact same result:

<array name="songsCoverArt">
   <item>R.drawable.coverart_indigo_big</item>
   ...
</array>

The ImageView is populated in SongAdapter.java:

@BindView(R.id.songTitle) TextView songTitle;
@BindView(R.id.songLength) TextView songLength;
@BindView(R.id.artistName) TextView artistName;
@BindView(R.id.albumTitle) TextView albumTitle;
@BindView(R.id.coverArt) ImageView coverArt;

public ViewHolder(View itemView) {
   super(itemView);
   ButterKnife.bind(this, itemView);
}

protected void clear() {
   songTitle.setText("");
   albumTitle.setText("");
   songLength.setText("");
   artistName.setText("");
   coverArt.setImageDrawable(null);
}

public void onBind(int position) {
    super.onBind(position);

    final Song song = SongList.get(position);

    if (song.getSongTitle() != null) {
         songTitle.setText(song.getSongTitle());
    }

    if (song.getAlbumTitle() != null) {
         albumTitle.setText(song.getAlbumTitle());
    }
    if (song.getSongLength() != null) {
         songLength.setText(song.getSongLength());
    }

    if (song.getArtistName() != null) {
         artistName.setText(song.getArtistName());
    }

     if (song.getCoverArt() != 0) {
         coverArt.setImageResource(song.getCoverArt());
     }

Here is the log output when the app is run. There are no errors in the logs. Notice the "0"s at the end of my debug output. That should be the id of the cover art drawables.

D/SongAdapter: Adding = Be There Jumper 3.4 Halton 0
D/SongAdapter: Adding = Indigo Jumper 4.40 Halton 0
D/SongAdapter: Adding = Kiss Me The Course 4.10 Radson 0
D/SongAdapter: Adding = Halfs Operatic 4.10 Jonesie 0
D/SongAdapter: Adding = Create Poisonous 3.90 Two People 0
D/SongAdapter: Adding = Bigger Proper Attire 4.12 Rotten 0
D/SongAdapter: Adding = Rave On Harlem 3.85 Trapper 0
D/SongAdapter: Adding = Yank Harley 3.90 Korix 0
D/SongAdapter: Adding = Line Up Harlem 3.95 Pepper Sky 0
D/SongAdapter: Adding = Please Cracked 4.05 Yellow 0
D/SongAdapter: Adding = Hurry Cracked 4.20 Yellow 0
D/SongAdapter: Adding = Proud Farsity 4.25 Cannon 0

The full github repo is here

Any help is appreciated

Cheryl Velez
  • 158
  • 8

3 Answers3

3

You can use TypedArray to access the resource values stored in the integer-array in your strings.xml . I have cloned your repository and made following adjustments to solve your problem. I have also made a pull request you can merge it. Here is my modification,

strings.xml

<resources>

...

<integer-array name="songsCoverArt">
    <item>@drawable/coverart_indigo_big</item>
    <item>@drawable/coverart_indigo_big</item>
    <item>@drawable/coverart_kissme_big</item>
    <item>@drawable/coverart_halfs_big</item>
    <item>@drawable/coverart_create_big</item>
    <item>@drawable/coverart_bigger_big</item>
    <item>@drawable/coverart_raveon_big</item>
    <item>@drawable/coverart_yank_big</item>
    <item>@drawable/coverart_lineup_big</item>
    <item>@drawable/coverart_hurry_big</item>
    <item>@drawable/coverart_hurry_big</item>
    <item>@drawable/coverart_proud_big</item>
</integer-array>

...

</resources>

MainActivity.java

...

private void prepareDefaultContent() {
        ArrayList<Song> songs = new ArrayList<>();
        //Resources r = recyclerView.getContext().getResources();

        String[] songTitle = getResources().getStringArray(R.array.songsTitles);
        String[] albumTitle = getResources().getStringArray(R.array.albumTitle);
        String[] songLength = getResources().getStringArray(R.array.songsLength);
        String[] artistName = getResources().getStringArray(R.array.artistName);

        TypedArray typedArray = getResources().obtainTypedArray(R.array.songsCoverArt);

        for (int i = 0; i < songTitle.length; i++) {

            int coverArtResourceId = typedArray.getResourceId(i, 0);

            Log.d(TAG, "Adding = " + songTitle[i] + " " + albumTitle[i] + " " + songLength[i] + " " + artistName[i] + " " + coverArtResourceId);

            songs.add(new Song(songTitle[i], albumTitle[i], songLength[i], artistName[i], coverArtResourceId));

        }

        typedArray.recycle(); // Important

        songAdapter.addItems(songs);
        recyclerView.setAdapter(songAdapter);

    }
...

SongDetail.java

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

    ...

    int BigCoverArt = intent.getIntExtra("coverArt", 0);

    ...
}

I hope it helps. Let me know if you face further difficulties?

Roaim
  • 2,298
  • 2
  • 11
  • 23
0

I would have commented but I'm just new, sorry in advance for dedicating a whole answer to this :). Storing R.drawable IDs in XML array Explains how you should get drawable ids from an xml array.

Snagtz
  • 118
  • 6
  • Thank you for trying to answer my question. The resource you linked does have similarities to the solution provided for my question. Thank you. – Cheryl Velez Sep 06 '19 at 17:46
0

If answer of ProfessionalCode will not help there is another (though quite old) post on SO about similar issue: Loading Integer Array from xml.

Also noted both links have <integer-array>, not just <array>.

Alex Martian
  • 3,423
  • 7
  • 36
  • 71
  • Thank you for trying to answer my question. The resource you linked does have similarities to the solution provided for my question, and I had seen this one in my "googling" for a solution, but it had some extras that didn't really apply. And I had totally overlooked the TypedArray part. From my inexperience with Java, I didn't notice the answer that was right in front of my face. :-) – Cheryl Velez Sep 06 '19 at 17:48