2016-10-04 1 views
3

J'ai une application que j'ai besoin d'adapter pour Android TV. Cette application contient RecyclerView horizontal et il ne défile pas lorsque j'appuie sur les boutons D-pad de la télécommande. J'ai trouvé this solution, mais il plante. Voici le code:Comment implémenter le défilement dans RecyclerView sur Android TV?

<ru.myapp.package.HorizontalPersistentFocusWrapper 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"> 
     <android.support.v7.widget.RecyclerView 
      android:id="@+id/recycler_view" 
      android:layout_width="match_parent" 
      android:layout_height="250dp" 
      android:background="@null" 
      android:scrollbars="none"/> 
</ru.myapp.package.HorizontalPersistentFocusWrapper> 

HorizontalPersistentFocusWrapper est le même que PersistentFocusWrapper mais mPersistFocusVertical = false;

crash occure dans ce lieu:

@Override 
    public void requestChildFocus(View child, View focused) { 
     super.requestChildFocus(child, focused); 
     View view = focused; 
     while (view != null && view.getParent() != child) { 
      view = (View) view.getParent(); <<<------ Crash here 
     } 
     mSelectedPosition = view == null ? -1 : ((ViewGroup) child).indexOfChild(view); 
     if (DEBUG) Log.v(TAG, "requestChildFocus focused " + focused + " mSelectedPosition " + mSelectedPosition); 
    } 

crash stacktrace:

java.lang.ClassCastException: android.view.ViewRootImpl cannot be cast to android.view.View 
     at ru.myapp.package.HorizontalPersistentFocusWrapper.requestChildFocus(HorizontalPersistentFocusWrapper.java:108) 
     at android.view.View.handleFocusGainInternal(View.java:5465) 
     at android.view.ViewGroup.handleFocusGainInternal(ViewGroup.java:714) 
     at android.view.View.requestFocusNoSearch(View.java:8470) 
     at android.view.View.requestFocus(View.java:8449) 
     at android.view.ViewGroup.requestFocus(ViewGroup.java:2747) 
     at android.view.View.requestFocus(View.java:8416) 
     at android.support.v4.widget.NestedScrollView.arrowScroll(NestedScrollView.java:1222) 
     at android.support.v4.widget.NestedScrollView.executeKeyEvent(NestedScrollView.java:551) 
     at android.support.v4.widget.NestedScrollView.dispatchKeyEvent(NestedScrollView.java:512) 
     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640) 
     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640) 

Répondre

4

Utilisez la dernière version de RecyclerView. Ou utiliser au moins
com.android.support:recyclerview-v7:23.2.0
Voir ce lien pour plus d'informations:
https://code.google.com/p/android/issues/detail?id=190526&thanks=190526&ts=1445108573

Maintenant, pour la partie importante:
Les nouvelles versions de RecyclerView ont commencé à obéir aux règles de ses enfants (comme la hauteur et la largeur) . Vous devez définir votre point de vue racine XML élément enfant à:
android:focusable="true"

Maintenant, le défilement sera comme il était prévu.

+0

Merci !!! J'ai résolu mon problème ... maintenant je peux faire défiler dans Recyclerview – skm

1

essayer. Travaille pour moi.

@Override 
public void requestChildFocus(View child, View focused) { 
    super.requestChildFocus(child, focused); 
    View view = focused; 
    while (view != null && view.getParent() != child) { 
     try { 
      view = (View) view.getParent(); 
     } catch (ClassCastException e) { 
      view = null; 
     } 
    } 
    mSelectedPosition = view == null ? -1 : ((ViewGroup) child).indexOfChild(view); 
    if (DEBUG) 
     Log.v(TAG, "requestChildFocus focused " + focused + " mSelectedPosition " + mSelectedPosition); 
} 
+0

Merci pour votre réponse. Avec ce code crashe ne se produit pas. Mais RecyclerView ne réagit pas sur d-pad. – BArtWell

+1

Juste pour être sûr. HorizontalPersistentFocusWrapper est utilisé pour envelopper un (des) RecyclerView (s) avec le gestionnaire LinearLayout vertical et éventuellement d'autres vues. Pour encapsuler RecyclerViews avec LineaLayoutManagers horizontal, veuillez utiliser VerticalPersistentFocusWrapper. –