2

I've made a list of artists, that once clicked bring up a list of albums. The idea is that once an album is clicked, the list of songs comes up.

Unfortunately, because there are two listviews being generated in this activity, the second 'onItemClick' method gets flagged in eclipse as 'duplicate'. Does anyone have any idea how to fix this?

Here is the main activity code:

package music.library;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MusicLibrary extends Activity implements OnItemClickListener {
  Cursor cursor;
  @SuppressWarnings("deprecation")
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    String[] columns = { 
            MediaStore.Audio.Artists._ID,
            MediaStore.Audio.Artists.ARTIST };

    cursor = managedQuery(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
        columns, null, null, null);

    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setOnItemClickListener(this);
    String[] displayFields = new String[] { MediaStore.Audio.Artists.ARTIST };
    int[] displayViews = new int[] { R.id.artistItem };
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.artist_item, cursor, displayFields, displayViews);
    listView.setAdapter(adapter);

  }


  @SuppressWarnings("deprecation")
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
    if (cursor.moveToPosition(position)) {

      String[] columns = {
          MediaStore.Audio.Media._ID,
          MediaStore.Audio.Media.ALBUM,
     };

      String where = android.provider.MediaStore.Audio.Media.ARTIST
          + "=?";

      String whereVal[] = { cursor.getString(cursor
          .getColumnIndex(MediaStore.Audio.Albums.ARTIST)) };

      String orderBy = android.provider.MediaStore.Audio.Media._ID;

      cursor = managedQuery(
          MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, columns,
          where, whereVal, orderBy);

      ListView listView = (ListView) findViewById(R.id.listView);
      String[] displayFields = new String[] { MediaStore.Audio.Media.ALBUM };
      int[] displayViews = new int[] { R.id.albumItem };
      SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
          R.layout.album_item, cursor, displayFields, displayViews);
      listView.setAdapter(adapter);

    }
  }


  @SuppressWarnings("deprecation")
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
        if (cursor.moveToPosition(position)) {

            String[] columns = { 
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.DISPLAY_NAME,
            };

            String where = MediaStore.Audio.Media.ALBUM
                + "=?";

            String whereVal[] = { cursor.getString(cursor
                .getColumnIndex(MediaStore.Audio.Albums.ALBUM)) };

            String orderBy = MediaStore.Audio.Media._ID;

            cursor = managedQuery(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns,
                where, whereVal, orderBy);

            ListView listView = (ListView) findViewById(R.id.listView);
            String[] displayFields = 
                    new String[] { MediaStore.Audio.Media.DISPLAY_NAME };
            int[] displayViews = new int[] { R.id.songItem };
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                    R.layout.song_item, cursor, displayFields, displayViews);
                listView.setAdapter(adapter);

    }
  }

}

Thanks for your help.

----Edit----

Thanks for the answers guys. Whilst all of the answers were great, I've chosen dymmeh's answer as my 'accepted' answer, as separating the views into different activities seems to make the most sense (even if this is not what I'd stated I was looking for in the initial question).

I ended up creating the following:

First class, showing artists:

package music.library;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MusicLibrary extends Activity implements OnItemClickListener {
  Cursor cursor;
  @SuppressWarnings("deprecation")
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    String[] columns = { 
            MediaStore.Audio.Artists._ID,
            MediaStore.Audio.Artists.ARTIST 
            };

    cursor = managedQuery(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
        columns, null, null, null);

    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setOnItemClickListener(this);
    String[] displayFields = new String[] { MediaStore.Audio.Artists.ARTIST };
    int[] displayViews = new int[] { R.id.artistItem };
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.artist_item, cursor, displayFields, displayViews);
    listView.setAdapter(adapter); }

    public void onItemClick(AdapterView<?> a, View v, int position, long id) {
        if (cursor.moveToPosition(position)) {

            String where = android.provider.MediaStore.Audio.Media.ARTIST
          + "=?";

            String whereVal[] = { cursor.getString(cursor
          .getColumnIndex(MediaStore.Audio.Albums.ARTIST)) };

    Intent intent = new Intent(MusicLibrary.this, AlbumSelection.class);
    intent.putExtra("where", where);
    intent.putExtra("whereVal", whereVal);
    startActivity(intent);

        }
     }
  } 

Second class, showing albums:

package music.library;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class AlbumSelection extends Activity implements OnItemClickListener {
  Cursor cursor;
  @SuppressWarnings("deprecation")
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Bundle extras = getIntent().getExtras();
    String where = extras.getString("where");
    String[] whereVal = extras.getStringArray("whereVal");

    String[] columns = {
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.ALBUM,
       };

        String orderBy = android.provider.MediaStore.Audio.Media._ID;

    cursor = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
        columns, where, whereVal, orderBy);

    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setOnItemClickListener(this);
    String[] displayFields = new String[] { MediaStore.Audio.Media.ALBUM };
    int[] displayViews = new int[] { R.id.albumItem };
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.album_item, cursor, displayFields, displayViews);
    listView.setAdapter(adapter); }

  public void onItemClick(AdapterView<?> a, View v, int position, long id) {
      if (cursor.moveToPosition(position)) {

        String where = android.provider.MediaStore.Audio.Media.ALBUM
        + "=?";

        String whereVal[] = { cursor.getString(cursor
        .getColumnIndex(MediaStore.Audio.Albums.ALBUM)) };

  Intent intent = new Intent(AlbumSelection.this, SongSelection.class);
  intent.putExtra("where", where);
  intent.putExtra("whereVal", whereVal);
  startActivity(intent);

       }    
    }
  } 

Third class, showing songs:

package music.library;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class SongSelection extends Activity implements OnItemClickListener {
    Cursor cursor;
      @SuppressWarnings("deprecation")
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Bundle extras = getIntent().getExtras();
        String where = extras.getString("where");
        String[] whereVal = extras.getStringArray("whereVal");

        String[] columns = {
                MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.TITLE,
                MediaStore.Audio.Media.DISPLAY_NAME,
                MediaStore.Audio.Media.MIME_TYPE,
           };

            String orderBy = android.provider.MediaStore.Audio.Media.TITLE;

        cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            columns, where, whereVal, orderBy);

        ListView listView = (ListView) findViewById(R.id.listView);
        listView.setOnItemClickListener(this);
        String[] displayFields = new String[] { MediaStore.Audio.Media.TITLE };
        int[] displayViews = new int[] { R.id.songItem };
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.song_item, cursor, displayFields, displayViews);
        listView.setAdapter(adapter); }

        public void onItemClick(AdapterView<?> a, View v, int position, long id) {
            if (cursor.moveToPosition(position)) {

        /*Intent intent = new Intent(AlbumSelection.this, SongSelection.class);
        intent.putExtra("ARTIST", artist);
        startActivity(intent);
*/
           }    
        }
      } 

And it's all working sweet.

Thanks heaps for all the responses. I'd be keen to hear any feedback on how this code might be tidied / made more efficient.

Thanks again.

4 Answers4

5

I found this solution. View.getId() will return value -1. So we cannot know if the item is clicked not not. Use adapter.getId() instead. It will return the correct item's Id.

 @Override
 public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
     if (adapter.getId() == R.id.ls_menu_genre) {
         //item was clicked
     }
 }
THANN Phearum
  • 1,969
  • 22
  • 19
4

You should use the method:

public void onItemClick(AdapterView<?> a, View v, int position, long id) {

just once. You can then do something like:

v.getId()

and do something like this:

@SuppressWarnings("deprecation")
public void onItemClick(AdapterView<?> a, View v, int position, long id) {

        if( v.getId() == R.id.listView ){
            if (cursor.moveToPosition(position)) {

                String[] columns = { 
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DISPLAY_NAME,
                };

                String where = MediaStore.Audio.Media.ALBUM
                    + "=?";

                String whereVal[] = { cursor.getString(cursor
                    .getColumnIndex(MediaStore.Audio.Albums.ALBUM)) };

                String orderBy = MediaStore.Audio.Media._ID;

                cursor = managedQuery(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns,
                    where, whereVal, orderBy);

                ListView listView = (ListView) findViewById(R.id.listView);
                String[] displayFields = 
                        new String[] { MediaStore.Audio.Media.DISPLAY_NAME };
                int[] displayViews = new int[] { R.id.songItem };
                SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                        R.layout.song_item, cursor, displayFields, displayViews);
            }
                    listView.setAdapter(adapter);
        }else{
            if (cursor.moveToPosition(position)) {

              String[] columns = {
                  MediaStore.Audio.Media._ID,
                  MediaStore.Audio.Media.ALBUM,
             };

              String where = android.provider.MediaStore.Audio.Media.ARTIST
                  + "=?";

              String whereVal[] = { cursor.getString(cursor
                  .getColumnIndex(MediaStore.Audio.Albums.ARTIST)) };

              String orderBy = android.provider.MediaStore.Audio.Media._ID;

              cursor = managedQuery(
                  MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, columns,
                  where, whereVal, orderBy);

              ListView listView = (ListView) findViewById(R.id.listView);
              String[] displayFields = new String[] { MediaStore.Audio.Media.ALBUM };
              int[] displayViews = new int[] { R.id.albumItem };
              SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                  R.layout.album_item, cursor, displayFields, displayViews);
              listView.setAdapter(adapter);

            }

        }


}
jsaye
  • 914
  • 7
  • 12
  • Hi jsaye. Thanks for your advice. Could you please provide an example of how you might use this in my particular activity, I have very limited java experience, and I am hacking this together as a bit of a side project while I read the basics of java. I'm actually reading programming in java for dummies at the moment! Anyhow I'd still love to be able to get this working, but I've got no idea how I would implement a switch/if else in this situation. Thanks for your time. –  May 03 '12 at 14:10
  • Hi @jsaye, I had try this. but it not going if always going to else. Which means id was return -1 every time from v.getId(); – Prasad Jan 18 '17 at 07:23
2

I see two ways of doing this

1.) Move your second onItemClick method contents into the first. Have a flag that determines if you are in artist or album listview and perform functionality in you onItemClick method based on that.

if (artistMode)
{
   //do artist mode stuff for clicks
}
else
{
  //do album mode stuff for clicks
}

2.) Do it the more "standard" way and split your album and artist views into separate activities. This way you aren't managing two sets of code in one file for something that normally would be done in two activities.

dymmeh
  • 22,247
  • 5
  • 53
  • 60
  • Thanks dymmeh. I like the idea of using separate activities, but I was reluctant to do so as I'm not sure how to carry the cursor position from one activity into the next.. Could you please shed some more light on how this might be achieved? Thanks for your time. –  May 03 '12 at 14:12
  • Sure! If you know the ID if your artist.. Ex. long artistId = 2 you can pass this ID as an extra in your intent to start the 2nd activity. Intent i = new Intent(this, YourSecondActivity.class); i.putExtra("ARTIST_ID", artistId); startActivity(i); – dymmeh May 03 '12 at 14:16
  • Then in your second activity you can retrieve the value in your onCreate method by calling: long artistId = getIntent().getLongExtra("ARTIST_ID", -1); We use Longs since database _Ids can end up being fairly large values. -1 is the default value if no value could be found – dymmeh May 03 '12 at 14:17
  • Thanks heaps dymmeh. It's late in Aus, and I've got work in the morning. I'm very grateful and I'll be sure to test this out first thing. I've done a little bit of tinkering with passing between activities, so this might not be out of my scope. Thanks again. –  May 03 '12 at 14:23
  • Nothing is out of your scope. You've got loads of info to scour through on here and google :) – dymmeh May 03 '12 at 14:30
0

Use only one onItemClick, then check which AdapterView you got and set an if in there based on that to handle both lists. But you'll need to have different adapter names, calling them both "adapter" is not going to work when trying to do this.

EDIT

Missed that you were re-using the same listview. New tack. Set a variable and use that to differentiate.

In MusicLibrary add:

private String currentList = "Artist";  // set the tracking variable to your initial list

Now your onClick should look like this:

public void onItemClick(AdapterView<?> a, View v, int position, long id) {
    if (currentList.equals("Artist")) {
        if (cursor.moveToPosition(position)) {
            String[] columns = {
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.ALBUM,
        };
        String where = android.provider.MediaStore.Audio.Media.ARTIST + "=?";
        String whereVal[] = { cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ARTIST)) };
        String orderBy = android.provider.MediaStore.Audio.Media._ID;

        cursor = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, columns, where, whereVal, orderBy);

        ListView listView = (ListView) findViewById(R.id.listView);
        String[] displayFields = new String[] { MediaStore.Audio.Media.ALBUM };
        int[] displayViews = new int[] { R.id.albumItem };
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.album_item, cursor, displayFields, displayViews);
        listView.setAdapter(adapter);
        currentList = "Album";  // re-set the list variable
    } else if (currentList.equals("Album")) {
        if (cursor.moveToPosition(position)) {
            String[] columns = { 
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.DISPLAY_NAME,
        };
        String where = MediaStore.Audio.Media.ALBUM + "=?";
        String whereVal[] = { cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM)) };
        String orderBy = MediaStore.Audio.Media._ID;

        cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns, where, whereVal, orderBy);

        ListView listView = (ListView) findViewById(R.id.listView);
        String[] displayFields = 
        new String[] { MediaStore.Audio.Media.DISPLAY_NAME };
        int[] displayViews = new int[] { R.id.songItem };
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.song_item, cursor, displayFields, displayViews);
        listView.setAdapter(adapter);
        currentList = "Songs";  // re-set the list variable
        }
    }
}
Barak
  • 16,318
  • 9
  • 52
  • 84
  • It seems to me (and it's late, past bedtime so I plan to test this out tomorrow) that this solution is giving the user a choice between the artist OR the album, and then when they click on one or the other the view changes accordingly. Preferably this particular activity would have the user picking the artist, then having to pick the album. I'm guessing I haven't completely understood what you're trying to explain.. How could an if statement decide which list to display if there is only one list choice possible at any given time? –  May 03 '12 at 14:20
  • You're thinking about it backwards, there is no choice for the user. The list defines what is sent to the click handler. When you click on the list one of the parameters passed is the AdapterView (ie the list adapter). In you on click you check which list it came from and handle appropriately. If it came from the artist list you execute the code to generate the album list. If it came from the album list you execute the code to generate the song list. – Barak May 03 '12 at 14:28