2015-09-19 14 views
12

używając najbardziej podstawowego przykładu z AppBarLayout i Toolbar, nie widzę animacji overscroll (blask od dołu ani góry) podczas próby przewijania więcej. Jednak jeśli rzucisz się na zawartość, pokaże ją.Lollipop AppBarLayout/Toolbar brakuje przeskakiwania animacji

Oto kod (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> 

następującą prostą Klasa aktywności:

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 fragment o RecycleView z zawartością przewijania aplikacji.

Jeśli jednak usunę AppBarLayout z xml i pozostawię otwarty pasek narzędzi (tylko komentarz otwierania i zamykania AppBarLayout), po przewinięciu będzie wyświetlać animację overscroll (blask).

Lub jeśli usuniesz layout_scrollFlags="scroll", wówczas overscroll będzie działał, ale nie będziesz mógł ukryć paska akcji podczas przewijania.

Dla dodatkowej informacji, debugowanie RecycleView, linia 2272

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

zawsze jest zakończone, gdy w tym AppBarLayout i nie kończy się, gdy go tam nie ma. Czy coś nadpisuje jego wydarzenia dotykowe?

Czy ktoś wie, kogo wyświetlić, aby przeskakiwać animację (blask) za pomocą AppBarLayout?

+0

Witam @ user654628 Czy masz jakieś aktualizacje na ten temat? mam ten sam problem co teraz: / – CodingBird

Odpowiedz

3

EDYTOWANIE: Wydaje się być ticket dla tego błędu. Możesz definitywnie zrobić to, co zrobił artur.dr ... @ gmail.com i rozszerzyć RecyclerView, aby zastąpić RecyclerView # dispatchNestedScroll, aby zawsze zwracać fałsz (pisze w swoim raporcie), że możesz przeskoczyć animacje, chociaż jestem tego pewien może coś zepsuć.

Niestety sposób w jaki RecyclerView jest kodowany i jak tworzony jest API NestedScrollingChild, nie ma sposobu na zachowanie pożądanego zachowania.

To jest z RecyclerView (23.1.1, jednak nie wierzę żadnej wersji, zanim to naprawi problem) wewnątrz metody 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); 
} 

Jak widzimy tutaj na javadoc dla dispatchNestedScroll (część API NestedScrollingChild) tak długo, jak nie ma jednego z rodziców, który zużywa zwój, RecyclerView nie będzie stosować żadnych dalekie przewinięcie animacji (Edge blask).

AppBarLayout zużywa przewijanie, a dokładniej tak długo, jak istnieje NestedScrollingParent, który zwraca wartość true w onStartNestedScroll, animacje przeskoku nie wystąpią.

CoordinatorLayout jest NestedScrollingParent, ale nie zwraca wartości true, chyba że istnieje opcja CoordinatorLayout.Behavior, która to robi. Domyślne zachowanie AppBarLayout implementuje tę metdo, aby zwrócić wartość true, gdy jest przewijanie w pionie + AppBarLayout ma coś do przewijania, a widok jest wystarczająco duży, aby przewijać.

// 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(); 

Flinging ma nieco innego podejścia, pozwalając na dalekie przewinięcie animacji dzieje się niezależnie od tego czy NestedScrollingParent zużywa przewijanie.

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; 
    } 
} 

Szczerze mówiąc nie mogę stwierdzić, czy to błąd, ponieważ logika ma sens. Jeśli przewijasz do górnej części widoku i masz coś zbliżonego do paska Zwijającego, to nie chcesz, aby animacja była zbyt duża. Istnieje jednak sposób na to, aby zachowanie mogło pochłonąć przewijanie x/y, aby zatrzymać animację. Dziwne jest również to, że kod do przewijania i rzucania jest inny.

Powiązane problemy