2015-01-30 18 views
32

sto creando una sottoclasse di ItemDecoration da questa sostanza: https://gist.github.com/alexfu/0f464fc3742f134ccd1eCome decorare in modo selettivo elementi RecyclerView

come farlo decorare solo oggetti con certe condizioni? Ad esempio, decorare solo gli elementi con determinate posizioni, tipo di ViewHolder, ecc

ho modificato la sostanza suddetta (più alcune modifiche obsoleto Android API) con questo codice, ma tutti gli articoli vengono decorate comunque:

public boolean isDecorated(View view, RecyclerView parent) { 
    RecyclerView.ViewHolder holder = parent.getChildViewHolder(view); 
    return holder instanceof MenuIconViewHolder || holder instanceof MenuDetailViewHolder; 
} 

@Override 
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
    if (isDecorated(view, parent)) { 
     if (mOrientation == VERTICAL_LIST) { 
      outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); 
     } else { 
      outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 
     } 
    } else { 
     super.getItemOffsets(outRect, view, parent, state); 
    } 
} 

Cosa c'è che non va nel codice sopra? A proposito, può essere considerata la migliore pratica (in relazione alla separazione delle preoccupazioni) per posizionare quel tipo di codice nella classe ItemDecoration?

+0

Mostraci cosa disegni nella tua classe. Da quello che abbiamo qui, stai semplicemente rimuovendo il padding per le linee indesiderate. –

+0

@StephaneMathis ecco il mio codice modificato: https://gist.github.com/anonymous/78a87dfc595d5efa8982 – akhyar

+0

Il metodo 'onDraw' della decorazione non ha alcun riferimento all'elemento corrente, quindi ho provato a fare il controllo' isDecorated' su ' getItemOffs'' – akhyar

risposta

27

È necessario chiamare isDecorated anche sul metodo di disegno, perché al momento non si posiziona l'offset su quegli elementi ma si continua a disegnare su di esso.

Il metodo esegue il ciclo su tutte le viste figlio attualmente presenti in RecyclerView visibili sullo schermo.

public void drawVertical(Canvas c, RecyclerView parent) { 
    final int left = parent.getPaddingLeft(); 
    final int right = parent.getWidth() - parent.getPaddingRight(); 

    final int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     final View child = parent.getChildAt(i); 
     if(isDecorated(child, parent)) 
     { 
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 
       .getLayoutParams(); 
      final int top = child.getBottom() + params.bottomMargin; 
      final int bottom = top + mDivider.getIntrinsicHeight(); 
      mDivider.setBounds(left, top, right, bottom); 
      mDivider.draw(c); 
     } 
    } 
} 

public void drawHorizontal(Canvas c, RecyclerView parent) { 
    final int top = parent.getPaddingTop(); 
    final int bottom = parent.getHeight() - parent.getPaddingBottom(); 

    final int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     final View child = parent.getChildAt(i); 
     if(isDecorated(child, parent)) 
     { 
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 
       .getLayoutParams(); 
      final int left = child.getRight() + params.rightMargin; 
      final int right = left + mDivider.getIntrinsicHeight(); 
      mDivider.setBounds(left, top, right, bottom); 
      mDivider.draw(c); 
     } 
    } 
} 
+0

Funziona, grazie! Non ho letto abbastanza attentamente da notare quel loop. Quindi, in sostanza, ogni chiamata a onDraw (normalmente) decorerà tutti gli elementi contemporaneamente. – akhyar

+1

Vorrei poter dare un +1 in più per l'utilizzo delle parole chiave 'final' – AllDayAmazing

+1

Vale la pena notare che le parole chiave finali non fanno assolutamente nulla in questo caso. Il compilatore da Java (5? 6?) Sa già come ottimizzare per questo. –