6

Hat jemand einen Weg gefunden, um Recyclerviews, AppbarLayouts und SwipeRefreshLayout auf 23.2 zusammen zu arbeiten? Ich verwende eine ziemlich normale Methode, denke ich, aber das swipe refreshlayout hält weiterhin die Scroll-Geste fest, wenn man versucht, die Recycleransicht nach oben zu verschieben.Recyclerviews und SwipeRefreshLayout mit Hilfe der Support-Bibliothek 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> 

mit folgenden Inneren

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

Antwort

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); 
     } 
    } 

} 

Es ist von http://nerd-is.in/2014-09/add-multi-child-view-in-swiperefreshlayout/

Erstellen Sie eine Ansicht SwipeRefreshLayout und benutzerdefinierte canChildScrollUp erweitern.

2

Konfrontiert gleich issue nach Aktualisierung auf 23.2.0. Es ist ein alt-neuer Fehler, der in 23.1.1 behoben wurde und wieder in 23.2.0 erscheint.

In meinem Fall ich Downgrade auf 23.1.1 und Everithith ist wieder in Ordnung. Also sollten wir auf eine neue Version der libs warten oder workarounds mit überschreiben SwipeRefreshLayout verwenden.


Hier Link zu Google Bugtracker: RecyclerView v23.2.0 - doesn't play nicely with SwipeRefreshLayout

5

Wenn Sie eine Ansicht setzen, die nicht ScrollingView nicht implementiert oder keine AbsListView in SwipeRefreshLayout, SwipeRefreshLayout#canChildScrollUp() immer false zurück.

So unter Verwendung eines FrameLayout innerhalb von SwipeRefreshLayout Sie zwei Probleme haben:

  1. SwipeRefreshLayout nicht verschachtelte Scroll-Operationen der Nachkomme Ansichten akzeptieren (siehe SwipeRefreshLayout#onStartNestedScroll(View, View, int)). Dies führt zu Problemen mit CoordinatorLayout/AppBarLayout.

  2. Die SwipeRefreshLayout Griffe Touch-Ereignisse selbst, solange ihr Kind nicht bewegen kann oder gibt es keine verschachtelten blättern im Gange (siehe SwipeRefreshLayout#onInterceptTouchEvent(MotionEvent) und SwipeRefreshLayout#onTouchEvent(MotionEvent)). Dies bedeutet, dass der Spinner angezeigt wird, wenn Sie "berührung nach unten" drücken.

Sie können dieses Problem beheben, indem Sie Ihre eigenen SwipeRefreshLayout verwenden, die SwipeRefreshLayout#onStartNestedScroll(View, View, int) überschreibt. Auf diese Weise verschachtelte Spiralen werden, auch wenn der direkte Kind Blick nach oben kann nicht akzeptiert:

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, wenn Sie bei SwipeRefreshLayout ‚s Code in 23.1.1 sehen Sie werden sehen, dass die canChildScrollUp() Kontrolle war entfernt, wurde aber in 23.2.0 erneut hinzugefügt.Ich entfernte auch den Scheck für !mReturningToStart, weil mReturningToStart immer false ist.

+0

Sie müssen diese Problemumgehung nicht mehr anwenden, da dies in 23.3.0 behoben ist. – segoh

Verwandte Themen