2015-09-18 15 views
24

Ich habe ein klassisches Layout mit einer ToolBar auf der Oberseite, einem TabLayout darunter, und einem ViewPager, der Tabs vom TabLayout umschaltet. Wenn der Inhalt des ViewPagers scrollbar ist, sollte die ToolBar außerhalb der Sichtweite verschwinden und das TabLayout sollte folgen und bleiben, wenn es den oberen Rand erreicht.Android CoordinatorLayout + AppbarLayout + Viewpager immer scrollen

All dies ist in meinem aktuellen Code gut, außer dass die ToolBar immer scrollbar ist, unabhängig von der Größe des ViewPager-Inhalts. Siehe meinen Code unten. Irgendwelche brillanten Ideen, wie das zu beheben ist?

<?xml version="1.0" encoding="utf-8"?> 
<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" 
    android:orientation="vertical"> 

    <android.support.design.widget.AppBarLayout 
     android:id="@+id/app_bar_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@color/primary" 
     android:orientation="vertical"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:theme="@style/AppTheme.ToolBar" 
      app:layout_scrollFlags="scroll|enterAlways" /> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/tabs" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="?attr/colorPrimary" 
      android:scrollbars="horizontal" 
      app:tabIndicatorColor="@color/black_text" /> 

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

    <android.support.v4.view.ViewPager 
     android:id="@+id/tabs_activity_view_pager" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

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

EDIT:

Ich kann sehen, dass die viewPager Höhe die gleiche wie die Höhe für die gesamte Stammansicht ist. Dies könnte beabsichtigt sein, da das appbar_scrolling_view_behavior scheinbar einen oberen und unteren Offset hinzufügt. Es erscheint jedoch seltsam, da es immer dazu führt, dass die Symbolleiste und die Tableiste durchgeblättert werden.

+0

Können Sie das besser erklären: "Die ToolBar sollte sich außer Sicht bewegen" und "die ToolBar ist immer scrollbar" Ich kann nicht verstehen, was das gesuchte Ergebnis ist – lubilis

+0

Das Ergebnis, wenn Inhalt in Viewpager scrollbar und gescrollt ist: Tabs Sticks Nach oben, die Symbolleiste wird herausgeklappt. Ergebnis, wenn Inhalt in ViewPager nicht gescrollt werden kann: ToolBar oben, TabLayout unten. – Kenneth

+2

Wenn der Inhalt des Viewpager nicht gescrollt werden kann, entfernen Sie die App: layout_behavior = "@ string/appbar_scrolling_view_behavior" –

Antwort

0

Basierend auf andere Proben, meinen eigenen Code, und der (etwas chaotisch) Quellcode der appbar_scrolling_view_behavior:

 public boolean onDependentViewChanged(CoordinatorLayout parent, View child, 
      View dependency) { 
     final CoordinatorLayout.Behavior behavior = 
       ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior(); 
     if (behavior instanceof Behavior) { 
      // Offset the child so that it is below the app-bar (with any overlap) 

      final int appBarOffset = ((Behavior) behavior) 
        .getTopBottomOffsetForScrollingSibling(); 
      final int expandedMax = dependency.getHeight() - mOverlayTop; 
      final int collapsedMin = parent.getHeight() - child.getHeight(); 

      if (mOverlayTop != 0 && dependency instanceof AppBarLayout) { 
       // If we have an overlap top, and the dependency is an AppBarLayout, we control 
       // the offset ourselves based on the appbar's scroll progress. This is so that 
       // the scroll happens sequentially rather than linearly 
       final int scrollRange = ((AppBarLayout) dependency).getTotalScrollRange(); 
       setTopAndBottomOffset(AnimationUtils.lerp(expandedMax, collapsedMin, 
         Math.abs(appBarOffset)/(float) scrollRange)); 
      } else { 
       setTopAndBottomOffset(dependency.getHeight() - mOverlayTop + appBarOffset); 
      } 
     } 
     return false; 
    } 

ich das Problem in einer Art und Weise zu lesen erklären, wie dieses Verhalten mit zu erwarten ist dieser Code.

Ich denke, wir müssen unser eigenes Scroll-Verhalten schreiben, die speziell für die RecyclerView,

+0

Kenneth, könnten Sie den Code 'appbar_scrolling_view_behavior' posten –

0

versuchen, diese Attribute auf TabLayout fügte hinzu:

app:layout_collapseMode="pin" 
app:tabMode="fixed" 

Und das auf AppBarLayout:

android:fitsSystemWindows="true" 

* UPDATE *

Ich habe versucht, und das ist nicht genug, da Symbolleiste immer noch scrollbar. Die Lösung besteht darin, etwas Logik über ViewPager (und seinen Inhalt) zu machen.

Entfernen Sie aus der XML-Layoutdatei das Attribut scroll_flag der Werkzeugleiste. Sie müssen einen Java-Code implementieren, um zu überprüfen, ob die Höhe des ViewPager-Inhalts> dann screenHeight - (toolbar + tabBar) ist. Wenn das stimmt, setzen programmatisch die scroll_flags wie folgt aus:

LayoutParams params; 
params = // get layout params from your toolbar 

params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL 
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); 

// set params 
toolbar.setLayoutParams(params); 
+0

Danke, aber kein Glück. – Kenneth

+0

Nochmals vielen Dank, aber immer noch kein Glück. Ich muss hinzufügen, dass der Inhalt in jedem ViewPager-Fragment natürlich variabel ist. Einige haben scrollbaren Inhalt, andere nicht. – Kenneth

+0

Ok, jetzt verstehe ich, versuche es mit meiner aktualisierten Antwort Vielleicht sollte ViewPager Android haben: layout_height = "match_parent"? – lubilis

4

Ich schlug vor, Sie this Probe versuchen.

Dies ist ein Layout wie Ihr Layout im Beispiel.

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

    <android.support.design.widget.AppBarLayout 
     android:id="@+id/appbar" 
     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:background="?attr/colorPrimary" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
      app:layout_scrollFlags="scroll|enterAlways" /> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/tabs" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

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

    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="end|bottom" 
     android:layout_margin="@dimen/fab_margin" 
     android:src="@drawable/ic_done" /> 

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

Das ist ziemlich viel, was ich bereits habe, und es hat das gleiche Problem ..? – Kenneth

+0

Dieses Beispiel ist ein Tutorial für Ihr Problem. Sie können Ihr Layout mit dem Muster implementieren. – MHossein

+0

Bitte beachten Sie meine Antwort unten. Das Beispielprojekt hat das gleiche Problem. https://www.dropbox.com/s/16fep4r7linjtnp/sameproblem.mov?dl=0 – Kenneth

0

Die ViewPager Höhe sollte match_parent und nicht wrap_content sein.

+0

Danke, aber es ändert nichts. – Kenneth

0

ich hatte gerade das gleiche Problem. Die Lösung ist sehr einfach, setzen Sie einfach Ihre viewpager Höhe

android:layout_height="wrap_content" 
-1

Einfache Lösung ist - wickeln Sie Ihre appbar layour und Seite-Viewer mit einer relativen Layout. - geben Sie Ihrem appbar Layout einige id - in der Seitenansicht Satz android: layout_below = "Your_appbar_layout" ZB:

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

<android.support.design.widget.AppBarLayout 
    android:id="@+id/your_appBar_ID" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@color/primary" 
    android:orientation="vertical"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:theme="@style/AppTheme.ToolBar" 
     app:layout_scrollFlags="scroll|enterAlways" /> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="?attr/colorPrimary" 
     android:scrollbars="horizontal" 
     app:tabIndicatorColor="@color/black_text" /> 

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

<android.support.v4.view.ViewPager 
    android:id="@+id/tabs_activity_view_pager" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/your_appBar_ID" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

</RelativeLayout> 

1

mit Listview als die Daten für ViewPager? Wenn ja, müssen Sie listView.setNestedScrollingEnabled(true);

0

ich das Problem gelöst haben, versucht, über das Beispiel Google-Vorlage und finden Sie heraus, dass

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

Linie in Sicht Pager Eigenschaften xml hinzugefügt werden müssen. Es hat mein Problem gelöst.