我有一个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);
}
对此事的任何帮助将不胜感激。我觉得我花了更多时间坚持这个比我应该做的更多!
答案 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);
};