2015-06-28 5 views
9

Ho un RecyclerView (con LinearLayoutManager) e un RecyclerView.ItemDecoration personalizzato per esso.Come gestire l'evento click in RecyclerView.ItemDecoration?

Diciamo che voglio avere pulsanti nella vista decorazione (per qualche motivo ..).

Gonfio il layout con il pulsante, disegna correttamente. Ma non posso rendere il pulsante selezionabile. Se premo su di esso, non accade nulla (rimane invariato, nessun effetto di compressione) e l'evento onClick non viene attivato.

La struttura del layout di ItemDecoration è

<LinearLayout> 
    <TextView/> 
    <Button/> 
</LinearLayout> 

e sto cercando di impostare ascoltatore in ViewHolder della decorazione

class ItemDecorationHolder extends RecyclerView.ViewHolder { 
    public TextView header; 
    public Button button; 

    public HeaderHolder(View itemView) { 
     super(itemView); 

     header = (TextView)itemView.findViewById(R.id.header); 
     button = (Button)itemView.findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       //.. Show toast, etc. 
      } 
     }); 
    } 
} 

e sto disegnando la decorazione in modo onDrawOver. (In realtà, sto modificando questo codice base: https://github.com/edubarr/header-decor)

Qualche idea? È fattibile?

Grazie!

risposta

6

Mentre l'intestazione reale è scorrere fuori dallo schermo, quella visibile viene disegnata direttamente sulla tela, non come un normale widget interattivo.

Sono disponibili le seguenti opzioni

  1. Override RecyclerView.onInterceptTouchEvent(), anche se con una certa invasività quindi preferisco quello successivo.
  2. Fare uso di RecyclerView.addOnItemTouchListener(), ricordare che l'argomento dell'evento di movimento è stato tradotto nel sistema di coordinate di RecyclerView.
  3. Utilizzare una vista di intestazione reale, ma ciò andrà un po 'lontano penso.

Se si prende l'opzione 1/2, Button.setPressed (vero) e ridisegnare l'intestazione avrà un effetto visivo stampa.

0

Come fa notare Neil, le cose si fanno più complicate di così. Comunque per definizione non puoi.

Quindi, perché non includere le buone librerie che lo fanno e altro? Propongo il mio duro lavoro per l'intestazione appiccicosa cliccabile nel mio progetto FlexibleAdapter, che utilizza una vista reale (non decoratori) per gestire gli eventi di clic sulle intestazioni quando appiccicose.

C'è anche una demo funzionante e una Wiki page su quella parte (e non solo).

2

In aggiunta a ciò che Neil ha detto, la risposta potrebbe aiutare. Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

E quindi basta calcolare l'altezza dell'intestazione e vedere se il clic cade su quella vista dell'intestazione e gestire l'evento da solo.

private class RecyclerViewOnGestureListener extends GestureDetector.SimpleOnGestureListener { 
    @Override 
    public boolean onSingleTapConfirmed(MotionEvent e) { 
     float touchY = e.getY(); 



     ALLog.i(this, "Recyclerview single tap confirmed y: " + touchY); 
     //mGroupHeaderHeight is the height of the header which is used to determine whether the click is inside of the view, hopefully it's a fixed size it would make things easier here 
     if(touchY < mGroupHeaderHeight) { 
      int itemAdapterPosition = mRecyclerView.getLayoutManager().getPosition(mRecyclerView.findChildViewUnder(0, mGroupHeaderHeight)); 

      //Do stuff here no you have the position of the item that's been clicked 
      return true; 
     } 
     return super.onSingleTapConfirmed(e); 

    } 

    @Override 
    public boolean onDown(MotionEvent e) { 
     float touchY = e.getY(); 

     if(touchY < mGroupHeaderHeight) { 
      return true; 
     } 
     return super.onDown(e); 
    } 

    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     float touchY = e.getY(); 

     if(touchY < mGroupHeaderHeight) { 
      return true; 
     } 
     return super.onSingleTapUp(e); 
    } 
} 
Problemi correlati