Fix settling behavior of BottomSheetBehavior

The bottom sheet now properly expands or collapses when user release
their finger with zero velocity.

Bug: 26988403
Change-Id: I271b305d7c0aa7d67e39be6b89bdb00eb4faf166
diff --git a/design/src/android/support/design/widget/BottomSheetBehavior.java b/design/src/android/support/design/widget/BottomSheetBehavior.java
index fbd725d..c7e7f3d 100644
--- a/design/src/android/support/design/widget/BottomSheetBehavior.java
+++ b/design/src/android/support/design/widget/BottomSheetBehavior.java
@@ -124,6 +124,8 @@
 
     private int mLastNestedScrollDy;
 
+    private boolean mNestedScrolled;
+
     private int mParentHeight;
 
     private WeakReference<V> mViewRef;
@@ -265,6 +267,7 @@
     public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child,
             View directTargetChild, View target, int nestedScrollAxes) {
         mLastNestedScrollDy = 0;
+        mNestedScrolled = false;
         return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
     }
 
@@ -302,12 +305,13 @@
         }
         dispatchOnSlide(child.getTop());
         mLastNestedScrollDy = dy;
+        mNestedScrolled = true;
     }
 
     @Override
     public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
         if (child.getTop() == mMinOffset || target != mNestedScrollingChildRef.get() ||
-                mLastNestedScrollDy == 0) {
+                !mNestedScrolled) {
             return;
         }
         int top;
@@ -318,6 +322,15 @@
         } else if (mHideable && shouldHide(child, getYVelocity())) {
             top = mParentHeight;
             targetState = STATE_HIDDEN;
+        } else if (mLastNestedScrollDy == 0) {
+            int currentTop = child.getTop();
+            if (Math.abs(currentTop - mMinOffset) < Math.abs(currentTop - mMaxOffset)) {
+                top = mMinOffset;
+                targetState = STATE_EXPANDED;
+            } else {
+                top = mMaxOffset;
+                targetState = STATE_COLLAPSED;
+            }
         } else {
             top = mMaxOffset;
             targetState = STATE_COLLAPSED;
@@ -328,6 +341,7 @@
         } else {
             setStateInternal(targetState);
         }
+        mNestedScrolled = false;
     }
 
     @Override
@@ -516,6 +530,15 @@
             } else if (mHideable && shouldHide(releasedChild, yvel)) {
                 top = mParentHeight;
                 targetState = STATE_HIDDEN;
+            } else if (yvel == 0.f) {
+                int currentTop = releasedChild.getTop();
+                if (Math.abs(currentTop - mMinOffset) < Math.abs(currentTop - mMaxOffset)) {
+                    top = mMinOffset;
+                    targetState = STATE_EXPANDED;
+                } else {
+                    top = mMaxOffset;
+                    targetState = STATE_COLLAPSED;
+                }
             } else {
                 top = mMaxOffset;
                 targetState = STATE_COLLAPSED;