2015-07-23 18 views
5

Ho un RecyclerView con solitamente due colonne e fino a otto. Utilizziamo molta navigazione D-PAD. Abbiamo un problema durante lo scorrimento, l'oggetto focalizzato salterà da sinistra a destra. Guarda le foto: enter image description hereRecyclerView scrolling

Ho notato che se gli elementi che vengono in seguito vengono memorizzati nella cache, non c'è alcun problema di messa a fuoco durante lo scorrimento. Un altro problema che ho è il mio oggetto di messa a fuoco può apparire sotto la mia intestazione appiccicosa. Questo non è desiderato. Quindi mi sento come se avessi fatto così quando lo scorrimento avrebbe una sorta di "soglia". In questo modo, quando il focus è all'interno di un elemento di essere fuori dallo schermo, scorrerà. In questo modo l'attenzione non è mai in basso o in alto.

Con questo in mente, ho provato questo approccio senza fortuna:

RecyclerView rv; 

@Override 
public void onFocusChange(View v, boolean hasFocus) { 
    if(!v.hasFocus()) { 
     Log.w(TAG, "View v did not have focus"); 
     return; 
    } 

    final int index = rv.getChildPosition(v); //adapter pos 
    if(index == NO_POSITION) { 
     Log.w(TAG, "Recycler view did not have view"); 
     return; 
    } 

    int position = rv.indexOfChild(v); // layout pos 
    int lastPos = rv.getChildCount(); // layout pos 
    int span = getLayoutManager().getSpanCount(); 
    int threshold = 2 * span; 
    Log.d(TAG, String.format("Position: %1$d. lastPos: %2$d. span: %3$d. threshold: %4$d", position, lastPos, span, threshold)); 

    if (position >= (lastPos - threshold)) { 
     //scroll down if possible 
     int bottomIndex = rv.getChildPosition(rv.getChildAt(lastPos)); 
     if (bottomIndex < getItemCount()) { 
      //scroll down 
      int scrollBy = v.getHeight(); 
      recycler.scrollBy(0, scrollBy); 
      Log.d(TAG, String.format("Scrolling down by %d", scrollBy)); 

     } 

    } else if (position <= threshold) { 
     //scroll up if possible 
     int topIndex = rv.getChildPosition(rv.getChildAt(0)); 
     if (topIndex > 0) { 
      //scroll up 
      int scrollBy = v.getHeight(); 
      recycler.scrollBy(0, -scrollBy); 
      Log.d(TAG, String.format("Scrolling up by %d", -scrollBy)); 
     } 
    } 
} 

Sono aperto a tutte le idee su come gestire la messa a fuoco durante lo scorrimento.

risposta

6

ho segnalato questo bug per AOSP issue tracker: issue 190526

come posso vedere dalla fonte il problema è dovuto al fatto GridLayoutManager usa implementazione LinearLayoutManager s' di onFocusSearchFailed() che viene chiamato quando messa a fuoco si avvicina al bordo interno della RecyclerView. L'implementazione di LinearLayoutManager offre solo l'elemento first/last (dipende dalla direzione di scorrimento). Quindi, la messa a fuoco passa al primo/ultimo elemento della nuova riga.

My workaround for this issue.

+1

Ho fatto qualcosa di simile, ma invece ho usato 'intercepFocusSearch()'. Grazie per aver postato l'errore! –

+0

ha funzionato per me! Grazie! – Crisic