18

Tôi đang làm việc trên một ứng dụng Android mà tôi đang sử dụng CoordinatorLayout, AppBarLayoutCollapsingToolbarLayout để sử dụng chức năng thanh thu gọn trước.Cách mở rộng AppBarLayout khi cuộn xuống đến ở đầu RecyclerView

Tôi đang sử dụng recyclerview để hiển thị số lượng mục trong đoạn. Khi tôi cuộn lên recyclerview nó trơn tru sụp đổ AppBarLayout nhưng khi tôi di chuyển xuống và đạt được trên mục đầu tiên của recyclerview nó sẽ tự động ngừng di chuyển mà không cần mở rộng `AppBarLayout '.

Sau đó, một lần nữa, tôi cần cuộn xuống lần nữa để hiển thị AppBarLayout. Vì vậy, yêu cầu của tôi là khi di chuyển xuống khi tôi đạt đến đầu recyclerview nó phải mở rộng `AppBarLayout '.

Làm cách nào chúng tôi có thể thực hiện việc này. Bất kỳ ý tưởng ? Xin vui lòng xem video của cùng https://www.dropbox.com/s/va5jk27ikytk5ax/app_collapsebar_issue.mp4?dl=0

Dưới đây là cách bố trí của tôi giống nhau: -

<?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

xin vui lòng gửi một số mã. –

+0

@VipulAsri Tôi đã chia sẻ bố cục của cùng một –

+0

[kiểm tra điều này] (http://stackoverflow.com/questions/33597447/expand-appbarlayout-when-recyclerview-is-scrolled-fling-to-top) –

Trả lời

9

Tôi vừa mới đặt cùng một sample app mà dường như để chứng minh hành vi mà bạn đang theo đuổi. AppBar sẽ tự động mở rộng bất cứ khi nào RecyclerView bên dưới nó được cuộn lên trên cùng, thay vì dừng và đợi một lần vuốt khác để mở AppBar.

Các thành phần có liên quan nhất nằm trong lớp tùy chỉnh RecyclerView. Tôi đã thêm một vài ý kiến ​​giải thích:

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

Xin chào, trong phương thức 'isAppBarCollapsed()' variable 'toolbarHeight' luôn chứa giá trị nhỏ hơn giá trị từ' appBarVisibleHeight' - cả hai giá trị đều không bằng nhau. –

+0

@IgorLevkivskiy Chỉ cần kiểm tra ra kho lưu trữ trong câu trả lời của tôi và nó vẫn có vẻ như làm việc. 'isAppBarCollapsed()' trả về true nếu AppBar được thu gọn hoàn toàn. – PPartisan

+0

Hành vi lạ trên API khác nhau. Bạn đã thử mã của bạn trên APi khác nhau? Nếu tôi chạy mã này trên 19 API - hoạt động tốt, nhưng nếu tôi chạy cùng một mã trên API 22 - nó hoạt động sai. Tôi cho rằng vấn đề có thể ở trạng thái ... Nhưng tôi không chắc chắn. –

Các vấn đề liên quan