6

Có ai đã tìm ra cách để có được recyclerviews, AppbarLayouts và SwipeRefreshLayout để làm việc cùng nhau trên 23.2 chưa? Tôi đang sử dụng một phương pháp khá chuẩn mà tôi nghĩ, nhưng swiperefreshlayout giữ lấy cử chỉ di chuyển khi cố gắng di chuyển lên recyclerview.Recyclerviews và SwipeRefreshLayout sử dụng thư viện hỗ trợ 23.2.0

<android.support.design.widget.CoordinatorLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <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" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:theme="?attr/toolbar_theme" 
      app:layout_scrollFlags="scroll|enterAlways" 
      android:elevation="4dp" /> 
    </android.support.design.widget.AppBarLayout> 
    <FrameLayout 
     android:id="@+id/fragment_container" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
     <!--fragment goes here --> 
    </FrameLayout> 
</android.support.design.widget.CoordinatorLayout> 

với những điều sau bên trong nó

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/swipe_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="?attr/window_background"> 
<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <ProgressBar 
     android:id="@+id/progress_bar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     style="@style/Widget.AppCompat.ProgressBar.Horizontal" 
     android:layout_marginTop="-4dp" 
     android:layout_marginBottom="-8dp" 
     android:elevation="17dp" 
     android:indeterminate="true" 
     android:visibility="invisible" /> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scrollbars="vertical" /> 
</FrameLayout> 
</android.support.v4.widget.SwipeRefreshLayout> 

Trả lời

6

attrs.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="ImprovedSwipeLayoutAttrs"> 
     <attr name="scrollableChildId" format="reference" /> 
    </declare-styleable> 
</resources> 

Layout.xml

<in.nerd_is.inactive_weibo.ui.ImprovedSwipeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:fab="http://schemas.android.com/apk/res-auto" 
    xmlns:isl="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/swipe_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/md_blue_grey_50" 
    isl:scrollableChildId="@+id/list_statuses" 
    tools:context="in.nerd_is.inactive_weibo.ui.StatusesFragment" > 

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

     <ListView 
      android:id="@+id/list_statuses" 
      android:minHeight="?android:attr/listPreferredItemHeight" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:paddingTop="12dp" 
      android:paddingBottom="12dp" 
      android:paddingLeft="8dp" 
      android:paddingRight="8dp" 
      android:clipToPadding="false" 
      android:divider="@android:color/transparent" 
      android:dividerHeight="12dp"/> 

     <com.melnykov.fab.FloatingActionButton 
      android:id="@+id/button_floating_action" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="bottom|right" 
      android:layout_margin="16dp" 
      android:src="@drawable/ic_md_create" 
      fab:fab_colorNormal="@color/md_blue_400" 
      fab:fab_colorPressed="@color/md_blue_grey_500"/> 
    </FrameLayout> 

</in.nerd_is.inactive_weibo.ui.ImprovedSwipeLayout> 

ImprovedSwipeLayout.java

public class ImprovedSwipeLayout extends SwipeRefreshLayout { 

    private static final String TAG = ImprovedSwipeLayout.class.getCanonicalName(); 
    private int mScrollableChildId; 
    private View mScrollableChild; 

    public ImprovedSwipeLayout(Context context) { 
     this(context, null); 
    } 

    public ImprovedSwipeLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     TypedArray a = context.obtainStyledAttributes(
       attrs, R.styleable.ImprovedSwipeLayoutAttrs); 
     mScrollableChildId = a.getResourceId(R.styleable.ImprovedSwipeLayoutAttrs_scrollableChildId, 0); 
     mScrollableChild = findViewById(mScrollableChildId); 
     a.recycle(); 
    } 

    @Override 
    public boolean canChildScrollUp() { 
     ensureScrollableChild(); 

     if (android.os.Build.VERSION.SDK_INT < 14) { 
      if (mScrollableChild instanceof AbsListView) { 
       final AbsListView absListView = (AbsListView) mScrollableChild; 
       return absListView.getChildCount() > 0 
         && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) 
         .getTop() < absListView.getPaddingTop()); 
      } else { 
       return mScrollableChild.getScrollY() > 0; 
      } 
     } else { 
      return ViewCompat.canScrollVertically(mScrollableChild, -1); 
     } 
    } 

    private void ensureScrollableChild() { 
     if (mScrollableChild == null) { 
      mScrollableChild = findViewById(mScrollableChildId); 
     } 
    } 

} 

Đó là từ http://nerd-is.in/2014-09/add-multi-child-view-in-swiperefreshlayout/

Tạo một Xem mở rộng SwipeRefreshLayout và canChildScrollUp tùy chỉnh.

2

Mặt cùng issue sau khi cập nhật thành 23.2.0. Đó là một lỗi cũ mới đã được sửa trong 23.1.1 và xuất hiện lại trong 23.2.0.

Trong trường hợp của tôi, tôi hạ cấp xuống 23.1.1 và everithing là OK một lần nữa. Vì vậy, chúng ta nên chờ phiên bản mới của libs hoặc sử dụng workarounds với ghi đè SwipeRefreshLayout.


Dưới đây là liên kết để google bugtracker: RecyclerView v23.2.0 - doesn't play nicely with SwipeRefreshLayout

5

Nếu bạn đặt một Xem mà không thực hiện ScrollingView hoặc không phải là một AbsListView vào SwipeRefreshLayout, SwipeRefreshLayout#canChildScrollUp() luôn trả về false.

Vì vậy, bằng cách sử dụng một FrameLayout bên trong SwipeRefreshLayout bạn có hai vấn đề:

  1. SwipeRefreshLayout không chấp nhận các hoạt động lồng cuộn quan điểm hậu duệ (xem SwipeRefreshLayout#onStartNestedScroll(View, View, int)). Điều này gây ra sự cố với CoordinatorLayout/AppBarLayout.

  2. SwipeRefreshLayout tự xử lý các sự kiện chạm miễn là con của nó không thể cuộn lên hoặc không có cuộn cuộn lồng nhau đang tiến hành (xem SwipeRefreshLayout#onInterceptTouchEvent(MotionEvent)SwipeRefreshLayout#onTouchEvent(MotionEvent)). Điều này có nghĩa là spinner được hiển thị khi "chạm di chuyển xuống".

Bạn có thể sửa lỗi này bằng cách sử dụng SwipeRefreshLayout của riêng bạn, ghi đè SwipeRefreshLayout#onStartNestedScroll(View, View, int). cách lồng này cuộn được chấp nhận ngay cả khi xem con trực tiếp không thể di chuyển lên:

public class SwipeRefreshLayout extends android.support.v4.widget.SwipeRefreshLayout { 

    public SwipeRefreshLayout(Context context) { 
     super(context); 
    } 

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

    @Override 
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { 
     return isEnabled() 
       && !isRefreshing() 
       && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; 
    } 
} 

BTW nếu bạn nhìn vào SwipeRefreshLayout 's mã trong 23.1.1 bạn sẽ thấy, rằng canChildScrollUp() kiểm tra là đã xóa nhưng đã được thêm lại trong 23.2.0.Tôi cũng đã xóa séc cho !mReturningToStart, bởi vì mReturningToStart luôn là false.

+0

Bạn không cần áp dụng giải pháp này nữa, vì điều này được khắc phục trong 23.3.0. – segoh

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