Code Lover
Code Lover

Reputation: 8378

Android - ArrayAdapter toggle ImageButton src between Play and Pause in ListView

I am still learning android. Here I need help to toggle between Play and Pause source in ImageButton in the ListView.

There should be only one song in Play state at a time. So if clicked other should stop.

enter image description here

SongAdapter.java

public class SongAdapter extends ArrayAdapter<Song> {

    public SongAdapter(@NonNull Context context, int resource, @NonNull List<Song> objects) {
        super(context, resource, objects);
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View playlistItemView = convertView;

        if (playlistItemView == null) {
            playlistItemView = LayoutInflater.from(getContext()).inflate(R.layout.playlist_item, parent, false);
        }

        Song currentSong = getItem(position);

        // get list item elements
        ImageView albumCoverThumbnail = playlistItemView.findViewById(R.id.playlist_album_thumbnail);
        TextView songTitle = playlistItemView.findViewById(R.id.playlist_song_title);
        TextView songAlbumTitle = playlistItemView.findViewById(R.id.playlist_song_album_title);
        TextView songArtist = playlistItemView.findViewById(R.id.playlist_song_artist);
        final ImageButton songPlayButton = playlistItemView.findViewById(R.id.playlist_play_button);

        // set data to the list item
        assert currentSong != null;
        albumCoverThumbnail.setImageResource(currentSong.getSongAlbumCoverId());
        songTitle.setText(currentSong.getSongTitle());
        songAlbumTitle.setText(currentSong.getSongAlbumTitle());
        songArtist.setText(currentSong.getSongSingers());

        // set song button action
        songPlayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                songPlayButton.setImageResource(R.drawable.ic_pause_black_24dp);
                Toast.makeText(getContext(), "Button clicked for item " + position, Toast.LENGTH_LONG).show();
            }
        });

        return playlistItemView;
    }

}

Song.java

public class Song {
    private String songAlbumTitle;
    private String songTitle;
    private String songSingers;
    private int    songAlbumCoverId;

    public Song(String albumTitle, String title, String singers, int albumCoverId) {

        songAlbumTitle = albumTitle;
        songTitle = title;
        songSingers = singers;
        songAlbumCoverId = albumCoverId;

    }

    public String getSongAlbumTitle() {
        return songAlbumTitle;
    }

    public String getSongTitle() {
        return songTitle;
    }

    public String getSongSingers() {
        return songSingers;
    }

    public int getSongAlbumCoverId() {
        return songAlbumCoverId;
    }
}

Activity.java

public class DreamVoyage extends AppCompatActivity {

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

        // get view ids
        ImageView albumCoverImage = findViewById(R.id.album_cover);

        // get intent extras
        Bundle bundle = getIntent().getExtras();
        // check if bundle in not null and containing value
        if (bundle != null) {

            String albumTitle = bundle.getString("album_one_title");
            String albumBand = bundle.getString("album_one_band");
            int albumCover = bundle.getInt("album_one_cover");

            albumCoverImage.setImageResource(albumCover);

            TextView albumTitleText = findViewById(R.id.album_title);
            TextView albumBandText = findViewById(R.id.album_band);

            albumTitleText.setText(albumTitle);
            albumBandText.setText(albumBand);

            ArrayList<Song> songs = new ArrayList<Song>();

            songs.add(new Song(albumTitle, "I do it for you", "Bryn Adams", albumCover));
            songs.add(new Song(albumTitle, "Here I am", "Bryn Adams", albumCover));

            SongAdapter songAdapter = new SongAdapter(this, 0, songs);

            ListView listView = findViewById(R.id.playlist_view);
            listView.setAdapter(songAdapter);


        }
    }
}

playlist_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:background="@drawable/border_bottom"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/playlist_album_thumbnail"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:src="@drawable/album_three"
        android:scaleType="centerCrop"
        android:contentDescription="@string/album_thumbnail_desc"/>

    <android.support.constraint.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        <TextView
            android:id="@+id/playlist_song_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Mon voyage de rêve"
            android:layout_marginLeft="8dp"
            android:textColor="#000000"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

        <TextView
            android:id="@+id/playlist_song_album_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Dream Voyage"
            android:textSize="10sp"
            android:textColor="#666666"
            app:layout_constraintTop_toBottomOf="@+id/playlist_song_title"
            app:layout_constraintStart_toStartOf="@id/playlist_song_title"/>

        <TextView
            android:id="@+id/playlist_song_credit_separator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=" - "
            android:textSize="10sp"
            android:textColor="#666666"
            app:layout_constraintTop_toBottomOf="@+id/playlist_song_title"
            app:layout_constraintStart_toEndOf="@id/playlist_song_album_title"/>

        <TextView
            android:id="@+id/playlist_song_artist"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=" - John Doen, Jane Doe"
            android:textSize="10sp"
            android:textColor="#666666"
            app:layout_constraintTop_toBottomOf="@+id/playlist_song_title"
            app:layout_constraintStart_toEndOf="@id/playlist_song_credit_separator"/>
    </android.support.constraint.ConstraintLayout>

    <ImageButton
        android:id="@+id/playlist_play_button"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:padding="0dp"
        android:layout_gravity="center_vertical"
        android:background="#00FFFFFF"
        android:src="@drawable/ic_play_arrow_black_24dp"
        android:scaleType="centerCrop"/>

</LinearLayout>

Upvotes: 1

Views: 90

Answers (1)

saiedmomen
saiedmomen

Reputation: 1441

Use a variable to store current playing items index

SongAdapter {
   int playingIndex = -1 //-1 means no song is playing
   .
   .
   .
}

Set play/pause drawable based on playingIndex and set the playingIndex in the songPlayButton.setOnClickListener

public View getView(final int position, ...) {
    if(playingIndex == position)
       songPlayButton.setImageResource(R.drawable.ic_play_black_24dp);
    else
       songPlayButton.setImageResource(R.drawable.ic_pause_black_24dp);

    songPlayButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(position == playIndex)
                playIndex = -1;
            else
                playIndex = position;
            notifyDataSetChanged();
        }
    });
}

It should get the job done. But it forces a redraw of all rows. In RecyclerView there is the notifyItemChanged method which can force redraw on single item.

You may try using the method here to update single row https://stackoverflow.com/a/3727813/4907678

My suggestion is migrating to RecyclerView and using notifyItemChanged.

cheers!

Upvotes: 2

Related Questions