18

Я работаю над одним Android-приложением, в котором я использую CoordinatorLayout, AppBarLayout и CollapsingToolbarLayout, чтобы использовать функциональность переходящего бара.Как развернуть AppBarLayout, когда прокрутка вниз достигает вершины RecyclerView

Я использую recyclerview для отображения количества элементов в фрагменте. Когда я прокручиваю recyclerview, он плавно сворачивает AppBarLayout, но когда я прокручиваю вниз и добираюсь до первого элемента recyclerview, он автоматически останавливает прокрутку без расширения `AppBarLayout '.

Затем снова нужно прокрутить вниз, чтобы сделать видимым AppBarLayout. Поэтому мое требование состоит в том, что при прокрутке вниз, когда я добираюсь до вершины recyclerview, он должен расширять `AppBarLayout '.

Как мы можем это сделать. Есть идеи ? Смотрите видео же https://www.dropbox.com/s/va5jk27ikytk5ax/app_collapsebar_issue.mp4?dl=0

Вот моя схема та же: -

<?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" 
    android:id="@+id/drawerLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 

    android:fitsSystemWindows="true"> 

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

    <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:id="@+id/coordinator" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:adjustViewBounds="true" 
     android:fitsSystemWindows="true" 
     app:layout_scrollFlags="scroll|exitUntilCollapsed" 
     > 

     <android.support.design.widget.AppBarLayout 
     android:id="@+id/app_bar" 
     android:layout_width="match_parent" 
     android:layout_height="220dp" 
     android:background="@drawable/offer_image" 
     android:fitsSystemWindows="true" 
     android:theme="@style/AppTheme.AppBarOverlay" 
     app:layout_scrollFlags="scroll|exitUntilCollapsed"> 

     <!-- <com.flaviofaria.kenburnsview.KenBurnsView 
      android:id="@+id/image" 
      android:layout_width="match_parent" 
      android:layout_height="220dp" 
      android:src="@drawable/offer_image" />--> 
     <android.support.design.widget.CollapsingToolbarLayout 
      android:id="@+id/toolbar_layout" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:fitsSystemWindows="true" 
      app:expandedTitleMarginEnd="64dp" 
      app:expandedTitleMarginStart="48dp" 
      app:layout_scrollFlags="scroll|exitUntilCollapsed"> 


      <com.flaviofaria.kenburnsview.KenBurnsView 
      android:id="@+id/image" 
      android:layout_width="match_parent" 
      android:layout_height="220dp" 

      android:src="@drawable/offer_image" /> 

      <FrameLayout 
      android:id="@+id/collapse_frame" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:background="#B3c85a00"> 

      </FrameLayout> 

      <FrameLayout 
      android:id="@+id/centerCircle" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center"> 

      <ImageView 
       android:id="@+id/imageViewCenter" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_gravity="center" 
       android:src="@drawable/offer" /> 
      </FrameLayout> 

      <include 
      android:id="@+id/toolbar" 
      layout="@layout/toolbar" /> 

      <android.support.design.widget.TabLayout 
      android:id="@+id/tabs" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_gravity="bottom" 
      android:layout_marginBottom="15dp" 
      app:tabIndicatorColor="#FFFFFF" 
      app:tabMode="scrollable" /> 
      <!--</FrameLayout>--> 
     </android.support.design.widget.CollapsingToolbarLayout> 
     </android.support.design.widget.AppBarLayout> 

     <!--<FrameLayout--> 

     <!--android:layout_width="match_parent"--> 
     <!--android:layout_height="match_parent"--> 
     <!-- --> 
     <!--android:visibility="visible">--> 

     <android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     style="@style/floating_action_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|end" 
     android:src="@drawable/ic_share_white_24dp" 
     android:visibility="gone" 
     app:backgroundTint="#FF9800" 
     app:elevation="6dp" 
     app:pressedTranslationZ="12dp" /> 

     <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/pager" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left|bottom|fill_vertical" 
     android:layout_marginTop="0dp" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v4.view.ViewPager> 
     <!--</FrameLayout>--> 

     <!--<include layout="@layout/content_scrolling" />--> 

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

    <RelativeLayout 
     android:id="@+id/bannerView" 
     android:layout_width="match_parent" 
     android:layout_height="58dp" 
     android:layout_gravity="bottom|center" 
     android:background="@drawable/curved_white_with_blue_border" 
     android:visibility="gone"> 

     <TextView 
     android:id="@+id/bannerText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_centerInParent="true" 
     android:layout_centerVertical="true" 
     android:gravity="center" 
     android:padding="3dp" 
     android:text="Banner" 
     android:visibility="gone" /> 

     <ImageView 
     android:id="@+id/bannerImage" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentLeft="true" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" 
     android:gravity="center" 
     android:padding="3dp" 
     android:scaleType="fitXY" 
     android:visibility="gone" /> 

     <ImageView 
     android:id="@+id/bannerClose" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" 
     android:layout_centerVertical="true" 
     android:src="@drawable/cross_icon" /> 
    </RelativeLayout> 


    <LinearLayout 
     android:id="@+id/socialTabs" 
     android:layout_width="match_parent" 
     android:layout_height="46dp" 
     android:layout_gravity="bottom|center" 
     android:layout_marginBottom="5dp" 
     android:background="@color/White" 
     android:orientation="horizontal" 
     android:visibility="gone"> 

     <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:adjustViewBounds="true" 
     android:src="@drawable/follow" /> 

     <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="center" 
     android:background="@color/White"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="46dp" 
      android:layout_gravity="center" 
      android:gravity="center" 
      android:paddingLeft="10dp" 
      android:paddingRight="10dp" 
      android:weightSum="3"> 

      <ImageView 
      android:id="@+id/facebookImageView" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_weight="1" 
      android:src="@drawable/fb_follow" /> 

      <ImageView 
      android:id="@+id/googlePlusImageView" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_marginLeft="5dp" 
      android:layout_marginRight="5dp" 
      android:layout_weight="1" 
      android:adjustViewBounds="true" 
      android:src="@drawable/google_follow" /> 

      <ImageView 
      android:id="@+id/twitterImageView" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_weight="1" 
      android:adjustViewBounds="true" 
      android:src="@drawable/twitter_follow" /> 
     </LinearLayout> 
     </FrameLayout> 
    </LinearLayout> 
    </FrameLayout> 

    <ExpandableListView 
    android:id="@+id/left_drawer" 
    android:layout_width="265dp" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:background="#fff" 
    android:choiceMode="singleChoice" 
    android:divider="@null" 
    android:dividerHeight="0dp" 
    android:drawSelectorOnTop="true" 
    android:groupIndicator="@null" 
    android:scrollbars="@null" /> 

</android.support.v4.widget.DrawerLayout> 
+0

пожалуйста, напишите код. –

+0

@VipulAsri Я поделился раскладкой того же –

+0

[проверить это] (http://stackoverflow.com/questions/33597447/expand-appbarlayout-when-recyclerview-is-scrolled-fling-to-top) –

ответ

9

Я просто положить вместе с sample app, который, кажется, чтобы продемонстрировать поведение вы после этого. AppBar будет автоматически расширяться всякий раз, когда RecyclerView под ним прокручивается вверх, а не останавливается и ждет еще одного прокрутки, чтобы открыть AppBar.

Наиболее релевантные компоненты находятся в обычном классе RecyclerView. Я добавил несколько пояснительных комментариев:

public class ScrollFeedbackRecyclerView extends RecyclerView { 

    private WeakReference<Callbacks> mCallbacks; 

    public ScrollFeedbackRecyclerView(Context context) { 
     super(context); 
     attachCallbacks(context); 
    } 

    public ScrollFeedbackRecyclerView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     attachCallbacks(context); 
    } 

    /*If the first completely visible item in the RecyclerView is at 
    index 0, then we're at the top of the list, so we want the AppBar to expand 
    **if the AppBar is also collapsed** (otherwise the AppBar will constantly 
    attempt to expand). 
    */ 
    @Override 
    public void onScrolled(int dx, int dy) { 
     if(((LinearLayoutManager)getLayoutManager()).findFirstCompletelyVisibleItemPosition() == 0) { 
      Log.e(getClass().getSimpleName(), "index 0 visible"); 
      if(mCallbacks.get().isAppBarCollapsed()) { 
       mCallbacks.get().setExpanded(true); 
      } 
     } 
     super.onScrolled(dx, dy); 
    } 

    /* the findFirstCompletelyVisibleItem() method is only available with 
    LinearLayoutManager and its subclasses, so test for it when setting the 
    LayoutManager 
    */ 
    @Override 
    public void setLayoutManager(LayoutManager layout) { 
     if(!(layout instanceof LinearLayoutManager)) { 
      throw new IllegalArgumentException(layout.toString() + " must be of type LinearLayoutManager"); 
     } 
     super.setLayoutManager(layout); 
    } 

    private void attachCallbacks(Context context) { 

     try { 
      mCallbacks = new WeakReference<>((Callbacks)context); 
     } catch (ClassCastException e) { 
      throw new ClassCastException(context.toString() + " must implement " + 
        "ScrollFeedbackRecyclerView.Callbacks"); 
     } 

    } 

    /* Necessary to interact with the AppBarLayout in the hosting Activity 
    */ 
    interface Callbacks { 

     boolean isAppBarCollapsed(); 
     void setExpanded(boolean expanded); 

    } 
} 

MainActivity.java

public class MainActivity extends AppCompatActivity implements ScrollFeedbackRecyclerView.Callbacks{ 

    private AppBarLayout mAppBarLayout; 
    private Toolbar mToolbar; 

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

     ScrollFeedbackRecyclerView mRecyclerView = (ScrollFeedbackRecyclerView) findViewById(R.id.rv_container); 
     RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(); 

     mRecyclerView.setAdapter(mAdapter); 
     mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 

     mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar); 
     mToolbar = (Toolbar) findViewById(R.id.toolbar); 

    } 

    /* When collapsed, calling getY() on the AppBar will return a negative number. 
    Adding this number to getHeight() will return the same value as the toolbar's 
    height if the AppBar is fully collapsed. 
    */ 
    @Override 
    public boolean isAppBarCollapsed() { 
     final int appBarVisibleHeight = (int) (mAppBarLayout.getY() + mAppBarLayout.getHeight()); 
     final int toolbarHeight = mToolbar.getHeight(); 
     return (appBarVisibleHeight == toolbarHeight); 
    } 

    @Override 
    public void setExpanded(boolean expanded) { 
     mAppBarLayout.setExpanded(expanded, true); 
    } 
} 
+0

Привет, в методе 'isAppBarCollapsed()' variable 'toolbarHeight' всегда содержит значение меньше значения из' appBarVisibleHeight' - оба значения никогда не равны. –

+0

@IgorLevkivskiy Просто протестировал хранилище в своем ответе, и он все еще работает. 'isAppBarCollapsed()' возвращает true, если AppBar полностью свернут. – PPartisan

+0

Это странное поведение в разных API. Вы пробовали свой код на разных APi? Если я запустил этот код в 19 API - отлично, но если я запустил тот же код в API 22, он работает неправильно. Я полагаю, проблема может быть в статусной строке ... Но я не уверен. –