0

Ich habe eine Recyclerview mit einer einfachen Liste von Elementen. Wenn Sie lange auf ein bestimmtes Element drücken, wird ein Audioelement, das mit diesem Element verknüpft ist (im Ordner "Assets" gespeichert), wiedergegeben. Beim Loslassen wird das Audio angehalten und kann durch langes Drücken an den pausierten Punkt zurückgestellt werden. Zu diesem Zweck habe ich im ViewHolder des RecyclerViews Adapters einen onTouchListener implementiert und eine Schnittstelle erstellt, die ich onBindViewHolder aufruft. Es funktioniert, aber wenn ich durch die Elemente scrolle, wird das Audio automatisch abgespielt und endlos wiederholt. Ich kann immer noch lange auf einen Gegenstand drücken und höre seinen Ton über dem automatisch wiederholenden Ton.OnTouchEvent ständig feuern beim Scrollen in RecyclerView

Ich bin mir nicht sicher, wo genau das Problem liegt. Ich bin mir nicht sicher, ob es sich um die Art und Weise handelt, in der Artikel in RecyclerView recycelt werden, da es sich beim Scrollen nur um ein Problem handelt. Ich habe versucht, einen onItemTouchListener im entsprechenden Fragment hinzuzufügen und die Arbeit dort drüben zu machen, hatte aber das gleiche Problem.

Oder vielleicht ist das Problem in wie ich meine onTouchListener und Schnittstelle eingerichtet habe? Ich bin mir nicht sicher, ob ich vollständig verstehe, was in onInterceptTouchEvent passieren soll.

Oder liegt das Problem vielleicht darin, wie ich meinen Mediaplayer im onTouchEvent eingerichtet habe?

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); 
} 

Jede Hilfe in dieser Angelegenheit würde sehr geschätzt werden. Ich fühle mich, als hätte ich mehr Zeit damit verbracht, als ich sollte!

Antwort

0

Sie sollten über die Verwaltung von Touch-Ereignisse in Sicht Gruppe http://developer.android.com/training/gestures/viewgroup.html

+0

Danke für die Antwort und Entschuldigung, ich habe nicht früher geantwortet. Ich habe versucht, herauszufinden, wie sich Berührungsereignisse ausbreiten - es scheint komplex zu sein. Ich verstehe nicht wirklich, welche Logik ich in onterceptTouchEvent schreiben sollte und was in onTouchEvent sein sollte. Ich habe ein paar Kombinationen von Dingen ausprobiert, die ich online gefunden habe, aber das Verhalten ist immer noch das gleiche. Funktioniert wie erwartet (Audio spielt während ACTION_DOWN und pausiert bei ACTION_UP), aber wenn ich scrolle, wird das zugehörige Audio des zuletzt berührten Elements automatisch und in einer Schleife abgespielt. Jeder andere Rat würde geschätzt werden. –

0

Sie anhängen können GestureDetector auf Ihre onTouchEvent() und dann schreiben Sie Ihre Logik in onLongPress() lesen.

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

Danke für die Antwort und Entschuldigung, ich habe nicht früher geantwortet. Sie haben Ihren Ansatz versucht, waren aber nicht sicher, wie Sie die Position und den Inhalt der jeweiligen Artikel referenzieren sollten? –

Verwandte Themen