Fragment中的RecyclerView不接受OnClick

时间:2017-10-30 15:53:53

标签: android android-fragments android-recyclerview

我的fragment中有MainActivity个小组,其中包含recyclerview。我想调用onClickItem类型的函数,以便我可以在列表中播放点击的歌曲名称。但我的onClick无效。

enter image description here

这是adapter

recyclerview
public class NowPlayingAdapter extends RecyclerView.Adapter<NowPlayingAdapter.PlayViewHolder> {

ArrayList<Audio> list = new ArrayList<>();
Context context;
private static final String TAG = "operation";

public interface NowPlayingInterface {
    void onSongClick(int position);
}

public NowPlayingInterface nowPlayingInterface;

public NowPlayingAdapter(ArrayList<Audio> list, Context context) {
    this.list = list;
    this.context = context;
    if(context instanceof NowPlayingAdapter.NowPlayingInterface){
        nowPlayingInterface = (NowPlayingInterface) context;
    }
}

@Override
public NowPlayingAdapter.PlayViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View v  = inflater.inflate(R.layout.play_list_item,parent,false);
    PlayViewHolder holder = new PlayViewHolder(v);
    return holder;
}

@Override
public void onBindViewHolder(NowPlayingAdapter.PlayViewHolder holder, int position) {
    final int pos = position;
    holder.songName.setText(list.get(position).getTitle());
    holder.duration.setText(list.get(position).getDuration());
    holder.album.setText(list.get(position).getAlbum());
    holder.removeItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Audio item = HomeFragment.audioList.get(pos);
            HomeFragment.audioList.remove(item);
            Log.e(TAG, "Remove: " );
            HomeFragment.nowPlayingAdapter.notifyDataSetChanged();
            Log.e(TAG, "Change: " );


        }
    });
}

@Override
public int getItemCount() {
    return list.size();
}

public class PlayViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    TextView songName, album, duration;
    ImageButton removeItem;
    RelativeLayout layout;

    public PlayViewHolder(View itemView) {
        super(itemView);
        layout = (RelativeLayout) itemView.findViewById(R.id.play_list_item);
        songName = (TextView) itemView.findViewById(R.id.songname);
        album = (TextView) itemView.findViewById(R.id.album);
        duration = (TextView) itemView.findViewById(R.id.duration);
        removeItem = (ImageButton) itemView.findViewById(R.id.remove_item_button);
    }

    @Override
    public void onClick(View v) {
        if(v==layout && nowPlayingInterface!=null)
        nowPlayingInterface.onSongClick(getAdapterPosition());
    }
}
} 

这是我的fragment课程,我想在recyclerview上调用点击功能。

public class HomeFragment extends Fragment implements NowPlayingAdapter.NowPlayingInterface {

protected RecyclerView currentPlaylistRecyclerView;
public static ArrayList<Audio> audioList = new ArrayList<>();
public static NowPlayingAdapter nowPlayingAdapter;
protected LinearLayoutManager layoutManager;

private TextView selectedSong = null;
private SeekBar seekBar = null;
private MediaPlayer player = null;
private ImageButton playButton = null;
private ImageButton prevButton = null;
private ImageButton nextButton = null;
private boolean isStarted = false;
private boolean isMovingSeekBar = false;
private String currentFile = null;
private String songName = null;
private String albumName = null;
private String duration = null;
private int filePosition;

private static final String TAG = "LibraryFragment";
private static final int UPDATE_FREQUENCY = 500;
private static final int SEEK = 5000;

private final Handler handler = new Handler();

private final Runnable updatePositionRunnable = new Runnable() {
    @Override
    public void run() {
        updatePosition();
    }
};

public HomeFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //fetchLocalAudioFiles();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView =  inflater.inflate(R.layout.fragment_home, container, false);
    rootView.setTag(TAG);

    currentPlaylistRecyclerView = (RecyclerView)rootView.findViewById(R.id.now_playing);
    layoutManager = new LinearLayoutManager(container.getContext());
    nowPlayingAdapter = new NowPlayingAdapter(audioList,container.getContext());
    currentPlaylistRecyclerView.setLayoutManager(layoutManager);
    currentPlaylistRecyclerView.setAdapter(nowPlayingAdapter);

    playButton = (ImageButton) rootView.findViewById(R.id.play);
    prevButton = (ImageButton) rootView.findViewById(R.id.prev);
    nextButton = (ImageButton) rootView.findViewById(R.id.next);
    selectedSong = (TextView) rootView.findViewById(R.id.selected_file);
    seekBar = (SeekBar) rootView.findViewById(R.id.seekbar);

    player = new MediaPlayer();
    player.setOnErrorListener(onError);
    player.setOnCompletionListener(onCompletion);
    seekBar.setOnSeekBarChangeListener(seekBarChanged);

    playButton.setOnClickListener(onButtonClick);
    prevButton.setOnClickListener(onButtonClick);
    nextButton.setOnClickListener(onButtonClick);

    return rootView;
}

@Override
public void onSongClick(int position) {
    Log.e(TAG, "Change: " );
    Audio item = audioList.get(position);
    filePosition = position;
    currentFile = item.getData();
    songName = item.getTitle();
    albumName = item.getAlbum();
    duration = item.getDuration();
    startPlay(currentFile);
}

4 个答案:

答案 0 :(得分:2)

您可以考虑在ViewHolder中添加setOnClickListener方法

public class PlayViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView songName, album, duration;
ImageButton removeItem;
RelativeLayout layout;

public PlayViewHolder(View itemView) {
    super(itemView);
    layout = (RelativeLayout) itemView.findViewById(R.id.play_list_item);
    songName = (TextView) itemView.findViewById(R.id.songname);
    album = (TextView) itemView.findViewById(R.id.album);
    duration = (TextView) itemView.findViewById(R.id.duration);
    removeItem = (ImageButton) itemView.findViewById(R.id.remove_item_button);
    //Setup for which view the onclick should be called
    layout.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    //since only 1 view has been setup for listening, no need of checking it's id
    if(nowPlayingInterface!=null)
    nowPlayingInterface.onSongClick(getAdapterPosition());
}

在此查看器的onClick中,您可以调用 nowPlayingInterface.onSingleClick();

有关此处接口的更多信息https://guides.codepath.com/android/Creating-Custom-Listeners

额外 - 我不知道你究竟需要一个RelativeLayout对象,但是如果它仅用于检测你项目中的点击,那么你可以摆脱它并简单地使用itemView.setOnClickListener(this);

另一个建议是,如果itemView(或layout)是您在Viewholder中为onClick设置的唯一视图,则可以避免检查它的ID。

答案 1 :(得分:1)

在适配器的点击监听器中使用类似 nowPlayingInterface.onSongClick(位置)的方式。这样,您的片段将能够处理点击事件并开始播放歌曲(希望如此)。 / p>

答案 2 :(得分:1)

为获取onBindViewHolder()中的位置,setTag为itemView的位置

holder.itemView.setTag(position);

然后您可以使用

获取onClick中的位置
int index = (int) view.getTag();

希望这有帮助

快乐编码

答案 3 :(得分:0)

您可能希望将onClickListener设置为侦听点击事件。

 public PlayViewHolder(View itemView) {
    super(itemView);
    layout = (RelativeLayout) itemView.findViewById(R.id.play_list_item);
    songName = (TextView) itemView.findViewById(R.id.songname);
    album = (TextView) itemView.findViewById(R.id.album);
    duration = (TextView) itemView.findViewById(R.id.duration);
    removeItem = (ImageButton) itemView.findViewById(R.id.remove_item_button);
    itemView.setOnClickListener(this);
}