0

我有一個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); 
} 

任何有關此事的幫助將不勝感激。我覺得我已經花了更多的時間在這個上,而不是我應該做的!

回答

0

你應該閱讀有關管理觸摸事件在視圖組 http://developer.android.com/training/gestures/viewgroup.html

+0

感謝您的回覆和抱歉,我沒有及時回覆。我一直在試着讓我的頭腦知道觸摸事件是如何傳播的 - 看起來很複雜。我不太明白我應該在onInterceptTouchEvent中寫什麼邏輯,以及onTouchEvent應該寫什麼。我嘗試了一些我在網上找到的東西的組合,但行爲仍然相同。按預期工作(在ACTION_DOWN期間播放音頻並在ACTION_UP上暫停),但是當我滾動最後一個觸摸項目的相關音頻時,將自動播放並循環播放。任何其他意見將不勝感激。 –

0

您可以將GestureDetectoronTouchEvent(),然後在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); 
    }; 
+0

感謝您的回覆和抱歉,我沒有及時回覆。嘗試了你的方法,但不知道如何參考各個項目的位置和內容? –