Search code examples
androidlistviewandroid-adaptersimplecursoradaptercursor-position

Android Studio - List View Image Button returning wrong positions


  • In my Android Studio app I have a list of songs from the SD card which I adapt into a list using a custom adapter and a cursor

  • in the list view, each list item has a "play" button next to it

  • when the button is clicked, it will start an intent containing the correspondings song ID

  • unfortunately it keeps passing an incorrect ID and when I check the position, it is nearly always "6" even though I click on different list items that are not in position 6

here is the code for iamge button being clicked

public class Adapter extends SimpleCursorAdapter {

public Context context;
public Cursor cursor;
public int layout;
public String[] selection;
public int[] resources;

public View convertView;

ImageButton playButton;
TextView songName;
TextView artist;
ImageView albumArt;



public Adapter(Context context, int layout, Cursor cursor, String[] selection, int[] resources, int flags) {
    super(context, layout, cursor, selection, resources, flags);
    this.context = context;
    this.layout = layout;
    this.cursor = cursor;
    this.resources = resources;
    this.selection = selection;

}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
        //inflates list
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(layout,parent,false);

        songName = (TextView) convertView.findViewById(resources[0]);
        artist = (TextView) convertView.findViewById(resources[1]);
        albumArt = (ImageView) convertView.findViewById(resources[2]);

    return convertView;
}

@Override
public void bindView(View view, Context context, final Cursor cursor) {
    super.bindView(view, context, cursor);

        final Cursor thisCursor = cursor;
        final Context thisContext = context;

        playButton = (ImageButton)  convertView.findViewById(R.id.listPlay);

        //set artist and text
        songName.setText(cursor.getString(cursor.getColumnIndex(selection[0])));
        artist.setText(cursor.getString(cursor.getColumnIndex(selection[1])));


        //artwork
        final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");

        try {
            Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, cursor.getLong(cursor.getColumnIndex(selection[2])));
            Bitmap songCoverArt = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
            albumArt.setImageBitmap(songCoverArt);
        }catch (Exception e){

        }

        //if play button is selected
        playButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                int position = thisCursor.getPosition();
                //returns wrong position and id's?


                //get id of song based on that position
                String stringID = cursor.getString(cursor.getColumnIndex(selection[3]));
                //create bundle to send
                Bundle bundle = new Bundle();
                //add position to bundle
                bundle.putString("ID", stringID);
                Intent intent = new Intent(thisContext, Home.class);
                intent.putExtras(bundle);
                //flag to allow this out of activty context
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                thisContext.startActivity(intent);
            }
    });
}

}

  • please note that cursor.getColumnIndex(selection[3]))) == MediaStore.Audio.Media._ID

  • if anyone could help me I would be so greatful!


Solution

  • I think, you should use the button's tag instead of a final variable(This will cause a Memory leak). I already ran into the same issue in the past, you should use the below adapter to resolve the issue,

     public class Adapter extends SimpleCursorAdapter {
    
    public Context context;
    public Cursor cursor;
    public int layout;
    public String[] selection;
    public int[] resources;
    
    public View convertView;
    
    ImageButton playButton;
    TextView songName;
    TextView artist;
    ImageView albumArt;
    
    
    
    public Adapter(Context context, int layout, Cursor cursor, String[] selection, int[] resources, int flags) {
        super(context, layout, cursor, selection, resources, flags);
        this.context = context;
        this.layout = layout;
        this.cursor = cursor;
        this.resources = resources;
        this.selection = selection;
    
    }
    
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
            //inflates list
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(layout,parent,false);
    
            songName = (TextView) convertView.findViewById(resources[0]);
            artist = (TextView) convertView.findViewById(resources[1]);
            albumArt = (ImageView) convertView.findViewById(resources[2]);
    
        return convertView;
    }
    
    @Override
    public void bindView(View view, Context context, final Cursor cursor) {
        super.bindView(view, context, cursor);
    
            //final Cursor thisCursor = cursor;
            final Context thisContext = context;
    
            playButton = (ImageButton)  convertView.findViewById(R.id.listPlay);
    
            //set artist and text
            songName.setText(cursor.getString(cursor.getColumnIndex(selection[0])));
            artist.setText(cursor.getString(cursor.getColumnIndex(selection[1])));
    
    
            //artwork
            final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
    
            try {
                Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, cursor.getLong(cursor.getColumnIndex(selection[2])));
                Bitmap songCoverArt = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
                albumArt.setImageBitmap(songCoverArt);
            }catch (Exception e){
    
            }
            playButton.setTag(cursor.getString(cursor.getColumnIndex(selection[3])));
            //if play button is selected
            playButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
    
                    //int position = thisCursor.getPosition();
                    //returns wrong position and id's?
    
    
                    //get id of song based on that position
                    String stringID = (String) v.getTag();
                    //create bundle to send
                    Bundle bundle = new Bundle();
                    //add position to bundle
                    bundle.putString("ID", stringID);
                    Intent intent = new Intent(thisContext, Home.class);
                    intent.putExtras(bundle);
                    //flag to allow this out of activty context
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    thisContext.startActivity(intent);
                }
        });
    }
    }