5

Sto creando un RecyclerView con l'intestazione in cui l'intestazione collassa mentre si scorre su RecyclerView. Posso raggiungerlo molto da vicino con il layout sottostante, con un AppBarLayout trasparente e MyCoolView che è l'intestazione. L'effetto di parallasse funziona alla grande.Prevenire RecyclerView dallo scorrimento in AppBarLayout prima che AppBarLayout venga compresso

Tuttavia, se l'intestazione è ancora visibile e lancio lo RecyclerView, il RV scorre lentamente verso l'alto e alcuni degli elementi si trovano sotto la barra degli strumenti finché il camper non raggiunge la parte superiore della vista. Ho giocato con lo scrollFlags ma non ho raggiunto un risultato desiderabile. Qualche suggerimento su come migliorare l'esperienza di fling in modo che gli oggetti non vengano tagliati?

visualizzare il video e guardare quando il suo schizzar --- https://www.dropbox.com/s/jppd6m7zo41k23z/20160609_151309.mp4?dl=0

<android.support.design.widget.CoordinatorLayout> 

    <android.support.design.widget.AppBarLayout 
     android:background="#00000000"> 

     <android.support.design.widget.CollapsingToolbarLayout 
      app:layout_scrollFlags="scroll|exitUntilCollapsed"> 

      <com.android.myapp.MyCoolView 
       app:layout_collapseMode="parallax"/> 

     </android.support.design.widget.CollapsingToolbarLayout> 

    </android.support.design.widget.AppBarLayout> 

    <android.support.v7.widget.RecyclerView/> 

</android.support.design.widget.CoordinatorLayout> 

risposta

5

Possibile soluzione (non testato). Aggiungi un OnOffsetChangedListener al tuo AppBarLayout e tieni nota del valore di offset. In primo luogo, dichiarare questo campo:

private boolean shouldScroll = false; 

Poi, onCreate:

AppBarLayout appbar = findViewById(...); 
appbar.addOnOffsetChangedListener(new OnOffsetChangedListener() { 
    @Override 
    void onOffsetChanged(AppBarLayout appbar, int offset) { 
     // Allow recycler scrolling only if we started collapsing. 
     this.shouldScroll = offset != 0; 
    } 
}); 

Ora, aggiungere un ascoltatore di scorrimento per il vostro RecyclerView. Ogni volta che si cerca di scorrere, ripristinare il rotolo se l'AppBarLayout è ancora ampliato:

RecyclerView recycler = findViewById(...); 
recycler.addOnScrollListener(new OnScrollListener() { 
    @Override 
    void onScrolled(RecyclerView recycler, int dx, int dy) { 
     // If AppBar is fully expanded, revert the scroll. 
     if (!shouldScroll) { 
      recycler.scrollTo(0,0); 
     } 
    } 
}); 

Questo potrebbe aver bisogno di qualche ritocco però. Vedo due problemi:

  • Possibile overflow dello stack se scrollTo() chiama onScrolled() indietro. Può essere risolto con un booleano o rimuovendo/aggiungendo l'ascoltatore di scorrimento
  • Forse si desidera impedire lo scorrimento non solo quando AppBarLayout è completamente espanso, ma più in generale quando AppBarLayout non viene compresso. Ciò significa che non è necessario verificare offset != 0, ma piuttosto per offset == appBarLayout.getTotalScrollRange(). Credo.
+0

funziona abbastanza bene. l'offset è sempre inferiore a zero, tranne quando completamente espanso. quindi 'offset> 0' non funzionerà. ho fatto qualcosa come 'shouldScroll = appbar.getTotalScrollRange() == Math.abs (offset)'. Non ottenere stackoverflow in modo che sembra funzionare. – ono

+0

Sì, ho dimenticato che è negativo. Hai fatto bene. – natario

+0

Questo non ha funzionato affatto per me. Qualcuno ha mai trovato una soluzione? Rende inutilizzabile borderline di appbarlayout. –

0

Forse puoi aggiungere layout_behavior = "@ string/appbar_scrolling_view_behavior" al tuo RecylerView come questo.

<android.support.v7.widget.RecyclerView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 
+0

Ce l'ho. Ho dimenticato di includerlo nell'XML qui sopra – ono

0

Avvolgere il RecyclerView in un FrameLayout risolve questo problema.

È inoltre necessario spostare appbar_scrolling_view_behavior da RecyclerView a FrameLayout in modo che venga posizionato correttamente sotto l'AppBarLayout.

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    > 

    <!--This RecyclerView MUST be wrapped in a FrameLayout--> 
    <!--This prevents the RecyclerView from going behind the AppBarLayout--> 
    <android.support.v7.widget.RecyclerView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     /> 

</FrameLayout> 
Problemi correlati