如何将数据从自定义 Android ListView ArrayAdapter(当它有多个 onClickEventListeners 时)传回其 fragment/activity

How to pass data from custom Android ListView ArrayAdapter (when it has multiple onClickEventListeners) back to its fragment/activity

我需要将数据 (videoId) 从这个自定义 ArrayAdapter 内部传递回当用户单击收藏夹按钮时保存它的片段。

如果用户点击歌曲的布局,我还需要将歌曲位置的数据传递回片段。 (下面定义了两个点击。)

以前,歌曲的位置是通过此方法传递给包含片段 SelectSongFragment 的:

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);
}
});

我给arrayAdapter添加了onclick Listeners后,mListView.setOnItemClickListener就停止工作了,现在我没有办法传回任何数据了!检查下面我的自定义 ArrayAdapter,并寻找 "HELP NEEDED HERE" 非常感谢!

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;
}
}

您可以为您的点击事件创建一个界面:

interface ClickEvents {
    void onFavoriteStarButtonClick(boolean isFavorite, int position);
    void onViewSongLayoutClick(int position);
}

ClickEvents 的实例指定为 ArrayAdapter 构造函数中的参数:

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;
}    

在您的 onClick 方法中调用 ClickEvents 的适当方法:

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);
    }
}

最后将 ClickEvents 的实现作为参数传递给您的适配器:

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);