Reputation: 1229
I need to PASS THE DATA (videoId) from inside this custom ArrayAdapter back to the fragment that holds it when the user clicks on the favorite button.
I also need to PASS THE DATA of the song's position back to the fragment if the user clicks the layout of the song. (Both onclicks defined below.)
Previously, the position of the song was passed to the containing fragment SelectSongFragment via this method:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//pass data to main activity
//TODO THIS NO LONGER RUNS
String songUrl = urlCleaner.parseIntoUrl(mSongs.getSong(i).getVideoId(), false);
passData(songUrl);
}
});
After I added the onclick Listeners to the arrayAdapter, mListView.setOnItemClickListener stopped working, and now I have no way to pass any data back! Check my custom ArrayAdapter below, and look for "HELP NEEDED HERE" Thanks very much!
public class SelectSongArrayAdapter extends ArrayAdapter<Song> implements AppInfo {
private ArrayList<Song> songs;
private ArrayList<String> mFavoriteSongs;
private boolean isFavorite = false;
private Song song;
/**
* Override the constructor for ArrayAdapter
* The only variable we care about now ArrayList<PlatformVersion> objects
* it is the list of the objects we want to display
*
* @param context
* @param resource
* @param objects
*/
public SelectSongArrayAdapter(Context context, int resource, ArrayList<Song> objects, ArrayList<String> favoriteSongVideoIds) {
super(context, resource, objects);
this.songs = objects;
this.mFavoriteSongs = favoriteSongVideoIds;
}
/**
* Primary functionality to create a list in the view of songs and song detail lines.
*
* @param position
* @param convertView
* @param parent
* @return
*/
public View getView(int position, View convertView, ViewGroup parent) {
// assign the view we are converting to a local variable
View view = convertView;
/*
Check to see if view null. If so, we have to inflate the view
"inflate" basically mean to render or show the view
*/
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.detail_line_song, null);
}
song = songs.get(position);
// obtain a reference to the widgets in the defined layout "wire up the widgets from detail_line"
TextView songTitle = (TextView) view.findViewById(R.id.songTitle);
TextView songDescription = (TextView) view.findViewById(R.id.songDescription);
View viewSongLayout = view.findViewById(R.id.songLayout); //For when user clicks left side of view
final ImageButton favoriteStarButton = (ImageButton) view.findViewById(R.id.favorite);
//Find out if song is favorite or not:
isFavorite = false;
for (String songId : mFavoriteSongs) {
if (song.getVideoId().equals(songId)) {
//Is not a favorite song. Do nothing
} else {
//Is a favorite song
isFavorite = true;
break;
}
}
//TODO Testing with multiple favorite songs.
songTitle.setText(song.getDisplayName());
songDescription.setText(song.getDescription());
favoriteStarButton.setPressed(isFavorite); //Changes star color
//Add Listeners
favoriteStarButton.setOnClickListener(new View.OnClickListener() { //Star button click
@Override
public void onClick(View v) {
isFavorite = !isFavorite;
if (isFavorite) {
//Add to favoriteVideoIds
/************************************************
HELP NEEDED HERE:
NEED TO PASS DATA (song.getVideoId()) BACK TO THE FRAGMENT SOMEHOW TO
REMOVE SONG FROM FAVORITES LIST OF SONGS STORED IN THE ACTIVITY
NOT HERE IN THE ARRAYADAPTER)
********************************************************************/
} else {
//remove from favoriteVideoIds
/************************************************
HELP NEEDED HERE:
NEED TO PASS DATA (song.getVideoId()) BACK TO THE FRAGMENT SOMEHOW TO
ADD SONG TO FAVORITES LIST OF SONGS STORED IN THE ACTIVITY
NOT HERE IN THE ARRAYADAPTER)
********************************************************************/
}
v.setPressed(isFavorite); //Changes star color
//redraw view
v.invalidate();
}
});
//Listener for when song is clicked (left side of listview)
viewSongLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/******************************************************************
SAME PROBLEM HERE. NEED TO PASS DATA (POSITION) OF THE SONG THAT WAS CLICKED BACK TO THE FRAGMENT.
********************************/
return view;
}
}
Upvotes: 1
Views: 466
Reputation: 2512
You can create an interface for your click events :
interface ClickEvents {
void onFavoriteStarButtonClick(boolean isFavorite, int position);
void onViewSongLayoutClick(int position);
}
Specify an instance of ClickEvents
as an argument inside your ArrayAdapter
constructor :
private ClickEvents clickEvents;
public SelectSongArrayAdapter(Context context, int resource, ArrayList<Song> objects, ArrayList<String> favoriteSongVideoIds, ClickEvents clickEvents) {
super(context, resource, objects);
this.songs = objects;
this.mFavoriteSongs = favoriteSongVideoIds;
this.clickEvents = clickEvents;
}
Call the appropriate methods of ClickEvents
inside your onClick
methods :
favoriteStarButton.setOnClickListener(new View.OnClickListener() { //Star button click
@Override
public void onClick(View v) {
isFavorite = !isFavorite;
clickEvents.onFavoriteStarButtonClick(isFavorite, position);
}
});
viewSongLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickEvents.onViewSongLayoutClick(position);
}
}
Finally pass an implementation of ClickEvents
to your adapter as a parameter :
final ClickEvents clickEvents = new ClickEvents() {
@Override
public void onFavoriteStarButtonClick(boolean isFavorite, int position) {
// FavoriteStarButton clicked
}
@Override
public void onViewSongLayoutClick(int position) {
// ViewSongLayout clicked
}
};
final SelectSongArrayAdapter selectSongArrayAdapter = new SelectSongArrayAdapter(getContext(), resource, objects, favoriteSongVideoIds, clickEvents);
Upvotes: 2