在RecyclerView

时间:2016-04-15 11:40:54

标签: android android-recyclerview android-mediaplayer ontouchevent

我有一个Recyclerview显示一个简单的项目列表。在长按特定项目时,播放与该项目相关联的音频(存储在资源文件夹中)。在释放时,音频暂停,并且可以通过长按返回到暂停点。为此,我在RecyclerViews Adapter的ViewHolder中实现了一个onTouchListener,并创建了一个我在onBindViewHolder中调用的接口。它可以工作但是当我滚动项目时,音频会自动播放并无休止地循环播放。我仍然可以长按一个项目并听到它在自动循环音频上播放的音频。

我不确定问题究竟在哪里。我不确定它是否与在RecyclerView中回收物品的方式有关,因为它只是滚动时出现问题的东西?我试图在相应的片段中添加一个onItemTouchListener并在那里完成工作,但是遇到了同样的问题。

或许问题在于我如何设置我的onTouchListener和界面?我不确定我是否完全理解onInterceptTouchEvent应该发生什么。

或者问题可能在于我如何在onTouchEvent中设置我的媒体播放器?

public class ClapsAdapter extends RecyclerView.Adapter<ClapsAdapter.ViewHolder> {

List<Clap> mItems;
private Context context;
ItemTouchListener itlistener;
GestureDetector mGestureDetector;


public interface ItemTouchListener {
    boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e, List<Clap> list);
    void onTouchEvent(List<Clap> list, View view, int position, MotionEvent me);
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}

@Override
public long getItemId(int position) {
    return position;
}

public ClapsAdapter(Context mContext, List<Clap> myClap) { 
    super();
    this.mItems = myClap;
    this.context = mContext;
    setHasStableIds(true);


    mItems = new ArrayList<Clap>();
    Clap mClaps = new Clap();
    mClaps.setCName("Hearty Clap");
    mClaps.setImageId(R.drawable.clapping1);
    mClaps.setAudio("applause-01.mp3");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Business Clap");
    mClaps.setImageId(R.drawable.clapping2);
    mClaps.setAudio("fake_applause.mp3");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Green Clap");
    mClaps.setImageId(R.drawable.clap3);
    mClaps.setAudio("laugh_and_applause.mp3");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Slow Clap");
    mClaps.setImageId(R.mipmap.slow_clap);
    mClaps.setAudio("fake_applause.mp3");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Emoji Clap");
    mClaps.setImageId(R.mipmap.clap_emoji);
    mClaps.setAudio("light_applause.mp3");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Slow Clap");
    mClaps.setImageId(R.mipmap.slow_clap);
    mClaps.setAudio("laughter-1.wav");
    mItems.add(mClaps);

    mClaps = new Clap();
    mClaps.setCName("Emoji Clap");
    mClaps.setImageId(R.mipmap.clap_emoji);
    mClaps.setAudio("laughter-2.mp3");
    mItems.add(mClaps);
   // this.itlistener = itl;
}

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnTouchListener{


    public  TextView title;
    public ImageView imageView;
    private ItemTouchListener touchListener;

    final MediaPlayer mp = new MediaPlayer();
    private Context mContext;
    List<Clap> mItems;

   public ViewHolder(View itemView) {
        super(itemView);

       imageView = (ImageView) itemView.findViewById(R.id.icon);
       title = (TextView) itemView.findViewById(R.id.description);
       itemView.setTag(itemView);
       itemView.setClickable(true);
       itemView.setOnTouchListener(this);


   }

    public void setTouchListener (ItemTouchListener itemTouchListener){
        this.touchListener = itemTouchListener;
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (touchListener != null) {
            touchListener.onTouchEvent(mItems, v, getAdapterPosition(), event);
        } return true;
    }




}


@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
    //Inflate the layout, initialize the View Holder
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_clap, parent, false);
    return new ViewHolder(v);

}


@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    Clap clap = mItems.get(position);
    holder.title.setText(mItems.get(position).getCName());
    holder.imageView.setImageResource(mItems.get(position).getImageId());


    final MediaPlayer mp = new MediaPlayer();

    holder.setTouchListener(new ItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e, List<Clap> list) {


            View childView = rv.findChildViewUnder(e.getX(), e.getY());
            if (childView != null && this != null && mGestureDetector.onTouchEvent(e)) {
                this.onTouchEvent(list, rv,rv.getChildAdapterPosition(childView), e);
            }

            return true;
        }

        @Override
        public void onTouchEvent(List<Clap> list, View view, int position, MotionEvent me) {
          // Toast.makeText(context, "TOUCH ME!!!",
             //       Toast.LENGTH_SHORT).show();

            switch (me.getAction()) {

                case MotionEvent.ACTION_DOWN: {

                    if (mp.isPlaying()) {
                        mp.stop();
                        mp.release();
                    }

                    try {
                        mp.reset();
                        AssetFileDescriptor afd;
                        afd = view.getContext().getAssets().openFd(mItems.get(position).getAudio());
                        mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                        mp.prepare();

                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mp.setLooping(true);

                    mp.start();
                }

                break;
                case MotionEvent.ACTION_UP: {
                    mp.pause();
                    Toast.makeText(context, mItems.get(position).getCName(),
                            Toast.LENGTH_SHORT).show();

                }
                break;

            }

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    });


}

@Override
public int getItemCount() {
    //returns the number of elements the RecyclerView will display
    //return items.size();
    return (null != mItems ? mItems.size() : 0);
}

public void insert(int position, Clap clap) {
    mItems.add(position, clap);
    notifyItemInserted(position);
}


public void remove(Clap clap) {
    int position = mItems.indexOf(clap);
    mItems.remove(position);
    notifyItemRemoved(position);
}

对此事的任何帮助将不胜感激。我觉得我花了更多时间坚持这个比我应该做的更多!

2 个答案:

答案 0 :(得分:0)

您应该阅读有关在视图组中管理触摸事件的信息 http://developer.android.com/training/gestures/viewgroup.html

答案 1 :(得分:0)

您可以将GestureDetector附加到onTouchEvent(),然后在onLongPress()中写下您的逻辑。

GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
        public void onLongPress(MotionEvent e) {
            //do something here
        }
    });

    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    };