2015-01-23 19 views
6

Ho un RecyclerView con GridLayoutManager, con 2 colonne per riga. Perché lo sviluppo è per Android TV, quindi ho bisogno di concentrarsi per navigare.Strange Android RecyclerView (GridLayoutManager) comportamento di messa a fuoco

enter image description here

E 'ok se sto usando premuto il tasto per navigare tutti gli elementi visibili. Ad esempio, Articolo 1 -> Articolo 3 -> Articolo 5 -> Articolo 7 (Solo parzialmente visibile.). Ma quando si preme di nuovo premuto il tasto, l'attenzione si sposterà alla voce 10, invece di 9.

enter image description here

La mia griglia adattatore di vista è:

public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> {  
    private ArrayList<String> mDataset; 

    public GridAdapter(ArrayList<String> myDataset) { 
     mDataset = myDataset; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
     View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.grid_item, viewGroup, false); 
     ViewHolder vh = new ViewHolder(v); 
     return vh; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     holder.txtTitle.setText(mDataset.get(position));  
    } 

    @Override 
    public int getItemCount() { 
     return mDataset.size(); 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder { 

     public TextView txtTitle; 
     public ViewHolder(View v) { 
      super(v); 
      txtTitle = (TextView) v.findViewById(R.id.title); 
     } 
    } 
} 

Qualsiasi idea di come risolvere questo problema? Grazie.

+1

hai fatto a finire risolvere questo? Questo ha rovinato la mia vita negli ultimi due mesi. – Dreamingwhale

+0

No, non ho ancora trovato nessuna soluzione. Ma non è molto critico nella mia applicazione, quindi l'ho tenuto lì. Spero che qualcuno possa risolvere il problema un giorno. –

+0

I documenti di navigazione dicono "Il framework Android applica automaticamente uno schema di navigazione direzionale basato sulla posizione relativa degli elementi focalizzabili nei vostri layout." Puoi impostare nextFocusDown, nextFocusUp, ecc. Nell'adattatore in qualche modo? – Elrond

risposta

0

Ho trovato una risposta su questo. Non ti permetterà di scorrere a meno che la nuova riga non sia gonfiata (quindi aspetterà che la nuova riga venga gonfiata) ma normalmente richiede meno di 50 ~ 100 ms. Quindi abbiamo concordato che il comportamento è accettabile.

Basta attivareFocusSearchFailed per restituire null. Ecco un esempio.

/** * Creato da sylversphere il 15-04-22. */public class DelayedNaviGridLayoutManager estende GridLayoutManager {

private final Context context; 

public SomeGridLayoutManager(Context context, int spanCount) { 
    super(context, spanCount); 
    this.context = context; 
} 

public SomeGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { 
    super(context, spanCount, orientation, reverseLayout); 
    this.context = context; 
} 

@Override 
public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) { 
    return null; 
}} 
+0

Non lavorare! La vista del riciclatore non crea nuova riga con questo codice ... – Crisic

+1

Non ha funzionato neanche per me. – BonderWu

1

View this related post e Vganin's answer per risolvere il problema.

ho segnalato questo bug per AOSP issue tracker: issue 190526

Come posso vedere dalla fonte il problema è dovuto al fatto GridLayoutManager utilizza implementazione di LinearLayoutManager di onFocusSearchFailed() che è chiamato quando lo stato attivo si avvicina al bordo interno del RecyclerView. L'implementazione di LinearLayoutManager offre solo l'elemento first/last (dipende da in direzione di scorrimento). Quindi la messa a fuoco passa al primo/ultimo elemento della nuova riga.

My workaround for this issue.

Problemi correlati