9

Da Bilder immer besser als Worte sind, präsentiere ich Ihnen my current layout.AppBarLayout mit recyclerView im verschachtelten Fragment

Die Symbolleiste/Registerkarten befinden sich in einer activity.xml mit einem viewPager, und die recycleView befindet sich in einem Fragment innerhalb des viewPagers. Sie können also nach rechts/links wischen, um andere Inhalte zu sehen.

Mein Problem ist, dass ich möchte, dass das AppBarLayout in seinem Scroll-Verhalten an die RecyclerView im ersten Fragment gebunden ist, aber nicht zu den anderen Fragmenten.

Im Code unten, habe ich diese Bindung, aber es funktioniert nicht, weil die RecyclerView das AppBarLayout im äußeren Layout nicht erkennt. Haben Sie einen Workaround dafür?

-Code für die Aktivität:

<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:fab="http://schemas.android.com/apk/res-auto" 
    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.support.v7.widget.Toolbar 
      android:id="@+id/toolbar_main" 
      android:layout_width="match_parent" 
      /* pretty stuff */ 
      app:layout_scrollFlags="scroll|enterAlways"> 

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

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

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

    <android.support.v4.view.ViewPager 
     android:id="@+id/main_pager" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <android.support.design.widget.SupportFloatingActionsMenu 
      ...> 
      /* Code for a fancy fab w/ menu */ 

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

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

Für das Fragment, das den recyclerView:

<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.insa.burnd.view.MainActivity.NewsfeedFragment" 
    android:id="@+id/fragment_newsfeed"> 

    <android.support.v4.widget.SwipeRefreshLayout 
     android:id="@+id/swipe_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/recyclerView" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 

    </android.support.v4.widget.SwipeRefreshLayout> 

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

Vielen Dank :)!

+0

Sie die gleiche Frage/Code hier gefragt: http://stackoverflow.com/questions/ 31144526/tablayout-inside-toolbar –

+0

Nein. Es ist nicht dasselbe. Die Frage ist sehr unterschiedlich, der Code ist ziemlich der gleiche (und das gif ist das gleiche). – Mehdi

Antwort

4

Sie können dies tun, indem Sie ViewPager.OnPageChangeListener implementieren und AppBarLayout.LayoutParams Scroll-Flags aktivieren/deaktivieren.

Hier ist ein Beispielcode:

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

     } 

     @Override 
     public void onPageSelected(int position) { 
      if (position == 0) { 
       //turn on scrolling 
       AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
       toolbarLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); 
       mToolbar.setLayoutParams(toolbarLayoutParams); 

       CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
       appBarLayoutParams.setBehavior(new AppBarLayout.Behavior()); 
       appBarLayout.setLayoutParams(appBarLayoutParams); 
      } else { 
       //turn off scrolling 
       AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
       toolbarLayoutParams.setScrollFlags(0); 
       mToolbar.setLayoutParams(toolbarLayoutParams); 

       CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
       appBarLayoutParams.setBehavior(null); 
       appBarLayout.setLayoutParams(appBarLayoutParams); 
      } 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 
    }); 

Aber es scheint nicht, wie ein gutes UX-Muster. Es wird für die Benutzer verwirrend sein.

+1

Danke! Es klappt :) ! Als ob es ein gutes UX-Muster ist, bin ich sehr besorgt darüber, aber die anderen Fragmente können auf keinen Fall gescrollt werden, also ist es vielleicht weniger verwirrend ... – Mehdi

+0

Es gibt zwar einen Fehler, aber ich denke, dass es keinen Weg gibt. .. – Mehdi

+0

Welcher Glitch? Kannst du es beschreiben? –

2

Ich denke, der Schlüssel zur Lösung Ihres Problems ist das Entfernen des Coordinatorlayouts aus dem Recyclerlayout.

Dies ist durch die acitivity_main.xml MainActivity mit einem Platzhalter Layout

<?xml version="1.0" encoding="utf-8"?> 
 
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
 
    xmlns:tools="http://schemas.android.com/tools" 
 
    android:id="@+id/drawer_layout" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="match_parent" 
 
    android:fitsSystemWindows="true" 
 
    tools:openDrawer="start"> 
 

 
    <include 
 
     layout="@layout/app_bar_main" 
 
     android:layout_width="match_parent" 
 
     android:layout_height="match_parent" /> 
 

 

 
    <android.support.design.widget.NavigationView 
 
     android:id="@+id/nav_view" 
 
     android:layout_width="wrap_content" 
 
     android:layout_height="match_parent" 
 
     android:layout_gravity="start" 
 
     app:itemIconTint="@color/drawer_item" 
 
     app:itemTextColor="@color/drawer_item" 
 
     android:fitsSystemWindows="true" 
 
     app:headerLayout="@layout/nav_header_main" 
 
     app:menu="@menu/activity_main_drawer" /> 
 

 
</android.support.v4.widget.DrawerLayout>
aufgeblasen

Dies ist der Inhalt-Layout mit den Laschen, AppBar und ViewPager

einzubeziehen

<?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" 
 
    xmlns:tools="http://schemas.android.com/tools" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="match_parent" 
 
    android:background="@color/grey_200" 
 
    tools:context=".activities.MainActivity"> 
 

 

 
    <android.support.design.widget.AppBarLayout 
 
     android:id="@+id/app_bar_layout" 
 
     android:layout_width="match_parent" 
 
     android:layout_height="wrap_content" 
 
     android:theme="@style/AppTheme.AppBarOverlay" 
 
     app:elevation="0dp"> 
 

 
     <android.support.v7.widget.Toolbar 
 
      android:id="@+id/toolbar" 
 
      android:layout_width="match_parent" 
 
      android:layout_height="?attr/actionBarSize" 
 
      android:background="?attr/colorPrimary" 
 
      app:layout_scrollFlags="scroll|enterAlways|snap" 
 
      app:popupTheme="@style/AppTheme.PopupOverlay" /> 
 

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

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

 

 
    <android.support.v4.view.ViewPager 
 
     android:id="@+id/container" 
 
     android:layout_width="match_parent" 
 
     android:layout_height="match_parent" 
 
     android:layout_marginLeft="8dp" 
 
     android:layout_marginRight="8dp" 
 
     android:layout_marginTop="12dp" 
 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v4.view.ViewPager> 
 

 

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

Und schließlich das RecyclerView Layout durch ein Fragment aufgeblasen.

<?xml version="1.0" encoding="utf-8"?> 
 

 
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
 
    android:id="@+id/your_recycler_view" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="match_parent" 
 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Wenn Sie ein guter Referenzcode möchten, können Sie die großartige Demo von Chris Banes von Google der CoordinatorLayout und andere Design-Support-Bibliothek Funktionen erstellt überprüfen.

Der vollständige Quellcode ist unter github zu finden.Dies war der einfachste Weg für mich, die Logik dahinter zu verstehen.

Ich hoffe, es hilft. (Ich habe endlich etwas hier gepostet!: D)

+0

app: layout_behavior = "@ string/appbar_scrolling_view_behavior" Dies wird den Viewpager dazu bringen, die Höhe von appBarLayout zu übersetzen, wenn es eine Ansicht layout_gravity = "bottom" im Fragmentlayout gibt, die überhaupt nicht sichtbar ist. – Sjd

4

Was ist mit all den verrückten Code/Layouts?

In den Fragmenten, wo Sie die Symbolleiste dies nicht wollen blättern, tun onCreateView() in das Fragment des:

recyclerView.setNestedScrollingEnabled(false);