4

У меня есть классonNestedScroll вызывается только один раз

public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { 
    public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { 
     super(); 
    } 

    public ScrollAwareFABBehavior() { 
     super(); 
    } 

    @Override 
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,final View directTargetChild, final View target, final int nestedScrollAxes) { 
     return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; 
    } 

    @Override 
    public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,final View target, final int dxConsumed, final int dyConsumed,final int dxUnconsumed, final int dyUnconsumed) { 
     super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); 
     if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { 
      child.hide(); 
     } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 
      child.show(); 
     } 
    } 
} 

проблема заключается в том, что onNestedScroll вызывается только один раз, когда я прокручиваю вверх recyclerview, поэтому ФАБ скрывается и снова никогда не показывает. Вот макет Я использую

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <android.support.v4.widget.SwipeRefreshLayout 
     android:id="@+id/refresh_layout" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
     <android.support.v7.widget.RecyclerView 
      android:id="@+id/list" 
      app:layoutManager="@string/vertical_linear_layout_manager" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"/> 
    </android.support.v4.widget.SwipeRefreshLayout> 
    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/add" 
     android:layout_width="wrap_content" 
     app:layout_behavior="mypackagename.util.ScrollAwareFABBehavior" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|end" 
     app:useCompatPadding="true" 
     android:layout_margin="16sp" 
     android:src="@drawable/ic_add"/> 
</android.support.design.widget.CoordinatorLayout> 

Моя поддержка библиотек версии 25.1.0

ответ

5

Я только answered абсолютно та же проблема в другом посте, проверьте его.

Говоря коротко, используйте следующее:

compile 'com.android.support:design:25.0.1' 
+0

Для записи, я недавно пытался переключиться на 'com.android.support: дизайн: 25.2.0' и такое поведение до сих пор то же самое. – ocramot

+0

Лучше этот ответ: https://stackoverflow.com/a/46727021/3397345 – Davidea

0

Не устанавливайте видимость FAB Унесенные в child.hide() - используйте вместо INVISIBLE. С 25.1.0 события прокрутки не передаются в представления, видимость которых GONE

+1

, но .hide() реализован внутри библиотеки поддержки – user3280437

18

Я решил проблему смены видимости с GONE на INVISIBLE со следующим кодом.

@Override 
public void onNestedScroll(CoordinatorLayout coordinatorLayout, final FloatingActionButton child, 
          View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { 
    super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, 
      dyUnconsumed); 

    if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { 
     child.hide(new FloatingActionButton.OnVisibilityChangedListener() { 
      @Override 
      public void onShown(FloatingActionButton fab) { 
       super.onShown(fab); 
      } 

      @Override 
      public void onHidden(FloatingActionButton fab) { 
       super.onHidden(fab); 
       child.setVisibility(View.INVISIBLE); 
      } 
     }); 
    } else if (dyConsumed <= 0 && child.getVisibility() != View.VISIBLE) { 
     child.show(); 
    } 
} 
+0

Спасибо. Оно работает. Это действительно не имеет смысла. – Kit

+1

@Kit, если представление 'GONE', оно больше не считается частью макета и поэтому не будет вызываться' LayoutBehavior' вида. Когда представление «INVISIBLE» является частью макета, но не отображается. – redwoolf

1
@Override 
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { 
    super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); 
    if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { 
     child.hide(new FloatingActionButton.OnVisibilityChangedListener() { 
      @Override 
      public void onHidden(FloatingActionButton fab) { 
       super.onHidden(fab); 
       fab.setVisibility(View.INVISIBLE); 
      } 
     }); 
    } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 
     child.show(); 
    } 
} 
+0

Этот ответ лучше ответа Эдуардо (меньше кода). Условие ('child.getVisibility()! = View.VISIBLE') также бесполезно. Я использую поддержку lib v27.0.2 – Davidea

Смежные вопросы