我有一個recyclerview顯示一個簡單的項目列表。長按特定項目時,播放與此項目相關的一段音頻(存儲在資產文件夾中)。釋放時,音頻暫停,可以通過長時間按鍵返回到暫停點。爲此,我在RecyclerViews適配器的ViewHolder中實現了一個onTouchListener,並創建了一個我在onBindViewHolder中調用的接口。它可以工作,但是當我滾動項目時,音頻將自動播放並無休止地循環播放。我仍然可以長時間按下一個項目,並聽到在自動循環音頻之上播放的音頻。OnTouchEvent在RecyclerView滾動時不斷觸發
我不確定問題出在哪裏。我不確定它是否與RecyclerView中的物品回收方式有關,因爲在我滾動時它只是一個問題。我試圖在相應的片段中添加一個onItemTouchListener,並在那裏進行工作,但遇到同樣的問題。
或者,也許問題在於我如何設置我的onTouchListener和接口?我不確定我完全理解onInterceptTouchEvent中應該發生什麼。
或者,這個問題可能在於我如何在onTouchEvent中設置我的mediaplayer?
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);
}
任何有關此事的幫助將不勝感激。我覺得我已經花了更多的時間在這個上,而不是我應該做的!
感謝您的回覆和抱歉,我沒有及時回覆。我一直在試着讓我的頭腦知道觸摸事件是如何傳播的 - 看起來很複雜。我不太明白我應該在onInterceptTouchEvent中寫什麼邏輯,以及onTouchEvent應該寫什麼。我嘗試了一些我在網上找到的東西的組合,但行爲仍然相同。按預期工作(在ACTION_DOWN期間播放音頻並在ACTION_UP上暫停),但是當我滾動最後一個觸摸項目的相關音頻時,將自動播放並循環播放。任何其他意見將不勝感激。 –