У меня есть recyclerview, отображающий простой список элементов. При длительном нажатии определенного элемента воспроизводится фрагмент звука, связанный с этим элементом (хранящийся в папке с ресурсами). При отпускании звук приостанавливается и может быть возвращен в паузу, долгое нажатие. С этой целью я реализовал onTouchListener в ViewHolder адаптера RecyclerViews и создал интерфейс, который я вызываю в onBindViewHolder. Он работает, но когда я просматриваю элементы, звук воспроизводится автоматически и циклически бесконечно. Я все еще могу долго нажимать на элемент и слышать его аудиовоспроизведение поверх автоматического аудио цикла.OnTouchEvent постоянно стреляет при прокрутке в RecyclerView
Я не уверен, где именно проблема. Я не уверен, связано ли это с тем, как элементы перерабатываются в 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);
}
Любая помощь по этому вопросу была бы весьма признательна. Мне кажется, что я потратил больше времени на это, чем должен!
Спасибо за ответ и жаль, что я не ответил раньше. Я пытался понять, как распространяются события касания - кажется, сложным. Я действительно не понимаю, какую логику я должен писать в onInterceptTouchEvent и что должно быть в onTouchEvent. Я пробовал несколько комбинаций вещей, которые я нашел в Интернете, но поведение по-прежнему остается прежним. Работает так, как ожидалось (звук воспроизводится во время ACTION_DOWN и приостанавливается на ACTION_UP), но когда я просматриваю связанный звук последнего затронутого элемента, он воспроизводится автоматически и в цикле. Будут оценены любые другие рекомендации. –