2015-09-19 17 views
12

utilizzando l'esempio più semplice con AppBarLayout e Barra degli strumenti, non riesco a vedere l'animazione overscroll (il bagliore dal basso o dall'alto) quando si prova a scorrere di più. Tuttavia, se scarichi il contenuto, lo mostrerà.Lollipop AppBarLayout/Barra degli strumenti mancante animazione overscroll

Ecco il codice (nav_drawer_toolbar_layout.xml):

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <!-- Replace fragments in this content frame, like a RecycleView --> 
    <FrameLayout 
     android:id="@+id/content_frame" 
     app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <android.support.design.widget.AppBarLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 
     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:minHeight="?attr/actionBarSize" 
      app:titleTextAppearance="@style/Base.TextAppearance.AppCompat.Title" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
      app:layout_scrollFlags="scroll|enterAlways"/> 
    </android.support.design.widget.AppBarLayout> 

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

Seguito da semplice Classe di attività:

public class MyActivity extends AppCompatActivity implements { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.nav_drawer_toolbar_layout); 

     // Setup the toolbar/actionbar 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FragmentManager manager = getFragmentManager(); 
     manager.beginTransaction().replace(R.id.content_frame, new MyFragmentList).commit(); 
    } 
} 

MyFragmentList è un frammento di un RecycleView con contenuti per scorrere l'applicazione.

Tuttavia se rimuovo AppBarLayout dall'xml e lascia aperta la barra degli strumenti (solo commento AppBarLayout di apertura e chiusura), mostrerà l'animazione overscroll (il bagliore) durante lo scorrimento.

Oppure se si rimuove layout_scrollFlags="scroll", l'overscroll funziona ma non è possibile nascondere la barra di azione quando si scorre.

Per informazioni supplementari, il debug RecycleView, linea 2272

if(this.mBottomGlow != null && !this.mBottomGlow.isFinished()) { 

è sempre finito quando compresi AppBarLayout e non finito quando non c'è. C'è qualcosa che sovrascrive i suoi eventi tattili?

Qualcuno sa a chi mostrare l'animazione overscroll (glow) con AppBarLayout?

+0

Ciao @ user654628 avete qualche aggiornamento su questo? Sto avendo lo stesso problema come te ora: / – CodingBird

risposta

3

MODIFICA: Sembra che ci sia un ticket per questo errore. Potresti definire esattamente ciò che artur.dr ... @ gmail.com ha fatto ed estendere RecyclerView per sovrascrivere RecyclerView # dispatchNestedScroll per restituire sempre false (scrive vero nel suo rapporto) è possibile ottenere animazioni di overscroll funzionanti, anche se sono abbastanza sicuro che potrebbe rompere qualcosa in linea.

Sfortunatamente come viene codificato RecyclerView e come viene eseguita l'API NestedScrollingChild non esiste un modo pulito per ottenere il comportamento desiderato.

Questo è da RecyclerView (23.1.1, tuttavia non credo alcuna versione prima che risolva il problema) all'interno del metodo scrollByInternal.

if (dispatchNestedScroll(consumedX, consumedY, unconsumedX, unconsumedY, mScrollOffset)) { 
    // Update the last touch co-ords, taking any scroll offset into account 
    mLastTouchX -= mScrollOffset[0]; 
    mLastTouchY -= mScrollOffset[1]; 
    if (ev != null) { 
     ev.offsetLocation(mScrollOffset[0], mScrollOffset[1]); 
    } 
    mNestedOffsets[0] += mScrollOffset[0]; 
    mNestedOffsets[1] += mScrollOffset[1]; 
} else if (ViewCompat.getOverScrollMode(this) != ViewCompat.OVER_SCROLL_NEVER) { 
    if (ev != null) { 
     pullGlows(ev.getX(), unconsumedX, ev.getY(), unconsumedY); 
    } 
    considerReleasingGlowsOnScroll(x, y); 
} 

Come si può vedere qui sul Javadoc per dispatchNestedScroll (parte dell'API NestedScrollingChild) fintanto che non v'è un genitore che consuma il rotolo, RecyclerView non verrà applicata alcuna animazione Overscroll (bagliore bordo).

AppBarLayout utilizza lo scorrimento, più precisamente finché esiste un oggetto NestedScrollingParent che restituisce true onStartNestedScroll, le animazioni di overscroll non si verificano.

CoordinatorLayout è un NestedScrollingParent ma non restituisce true a meno che non sia presente un CoordinatorLayout.Behavior. Il comportamento predefinito di AppBarLayout implementa questo methdo per restituire true quando c'è lo scrolling verticale + AppBarLayout ha qualcosa da scorrere + view è abbastanza grande da scorrere.

// Return true if we're nested scrolling vertically, and we have scrollable children 
// and the scrolling view is big enough to scroll 
final boolean started = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 
      && child.hasScrollableChildren() 
      && parent.getHeight() - directTargetChild.getHeight() <= child.getHeight(); 

lanciando ha un approccio leggermente diverso, consentendo l'animazione Overscroll accadendo a prescindere se la NestedScrollingParent sta consumando lo scorrimento.

if (!dispatchNestedPreFling(velocityX, velocityY)) { 
    final boolean canScroll = canScrollHorizontal || canScrollVertical; 
    dispatchNestedFling(velocityX, velocityY, canScroll); 

    if (canScroll) { 
     velocityX = Math.max(-mMaxFlingVelocity, Math.min(velocityX, mMaxFlingVelocity)); 
     velocityY = Math.max(-mMaxFlingVelocity, Math.min(velocityY, mMaxFlingVelocity)); 
     mViewFlinger.fling(velocityX, velocityY); 
     return true; 
    } 
} 

Onestamente non posso dire se questo è un errore perché entrambe le logiche hanno senso. Se si sta scorrendo verso la parte superiore della vista e si ha qualcosa di simile a una CollapsingToolbar, non si desidera che si verifichi un'animazione di tipo overscape. Tuttavia, esiste un modo per farlo in modo che il comportamento possa consumare la quantità x/y di scorrimento per impedire che l'animazione si verifichi. È anche strano che entrambi i codici per lo scrolling e il flinging siano diversi.

Problemi correlati