在RecyclerView

时间:2017-09-04 15:25:39

标签: java android android-recyclerview android-mediaplayer

我正在学习android和当前的RecyclerView,因此在这个例子中,我在点击播放按钮时播放特定的原始声音文件,然后在完成后释放它。 我可以认真地使用一些关于什么是最佳实践的指针,因为我有一些问题和问题:

  • 我遇到了转换状态的问题,所以如果我很快按下播放,我会得到 IllegalStateException ,可能是因为尝试释放已经发布的播放器。
  • 我显然也应该在发布后取消并在之前执行 null 检查,但由于我在嵌套范围内使用它,因此必须将其声明为final并且不能为空这令人困惑,我显然错过了一些东西。
  • onBindViewHolder 中的项目上设置clickListner似乎比在 viewHolder 类中的整行上添加clickListner要慢得多且响应速度慢。

使用RecyclerView设置mediaPlayer和正确管理资源的最佳做法是什么?我做错了什么会导致崩溃和"慢度"?

// ViewHolder

public static class myHolder extends RecyclerView.ViewHolder implements View.OnClickListener{


    ImageView playBtn;

    public myHolder(View v){
        super(v);
        playBtn = (ImageView) v.findViewById(R.id.playBtn);
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
    }

}

// onBindViewHolder / onCompletionListener

  @Override
public void onBindViewHolder(myHolder holder, int position) {
    myClass item = itemList.get(position);
    final MediaPlayer mediaPlayer = MediaPlayer.create(holder.itemView.getContext(), item.getAudioSource());

   holder.playBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {

            mediaPlayer.start();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mp.release();
                }
            });
        }
    });
}

2 个答案:

答案 0 :(得分:0)

如果您只是在用户互动中收听,则可以放弃setOnCompleteListener(),而是在(按顺序)OnLongClickListener()OnClickListener中定义播放/停止代码。像这样:

holder.playBtn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
       //Code to stop playing and release resources
    }
});

holder.playBtn.setOnLongClickListener(new View.OnClickListener(){
        @Override
        public void onLongClick(View v) {
           //Code to start playing 

           return false; //!!This is important so that OnClick() would be called after releasing the button
        }
    });

答案 1 :(得分:0)

OBS当我回答我自己的问题时,我不能说这是一个非常好的做法,但它确实解决了我遇到的问题,如果有人发现错误或有更好的更有效的方式,那么请发一个答案,阐述。

  • 而不是在onBindViewHolder中声明MediaPlayer,我把它变成了一个类变量,这让我可以避免让它最终并且能够在发布后使​​它无效。
  • 然后我在onClick方法中定义它,以确保它永远不会为null并且总是在需要时声明。
  • 我必须让我的持有人和“item”最终才能在onClick中使用它们但是这似乎有用(我猜想是recyclerView魔术)

应用程序不再崩溃,onCompletionListener应清除所有资源,这是当前代码:

//类变量mediaplayer和onCompletionListener方法

MediaPlayer mediaPlayer;

//onCompletionListener method
MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        mediaPlayer = null;
    }
};

// onBindViewHolder

@Override
public void onBindViewHolder(final itemHolder holder, int position) {
    final Items item = mItemList.get(position);

    holder.playBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            mediaPlayer = MediaPlayer.create(holder.itemView.getContext(), item.getAudioSource());
            if(mediaPlayer != null) {
                mediaPlayer.start();
                mediaPlayer.setOnCompletionListener(mCompletionListener);
            }
        }
    });
}