Browse Source

Merge pull request #404 from plusCubed/master

Fix remaining divider visibility (scroll listener) problems
Aidan Follestad 10 years ago
parent
commit
e96638a875

+ 69 - 54
library/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java

@@ -58,7 +58,9 @@ public class MDRootLayout extends ViewGroup {
     private int mButtonHorizontalEdgeMargin;
 
     private Paint mDividerPaint;
-    private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
+
+    private ViewTreeObserver.OnScrollChangedListener mTopOnScrollChangedListener;
+    private ViewTreeObserver.OnScrollChangedListener mBottomOnScrollChangedListener;
 
     public MDRootLayout(Context context) {
         super(context);
@@ -202,7 +204,6 @@ public class MDRootLayout extends ViewGroup {
             } else {
                 mUseFullPadding = false;
                 availableHeight = 0;
-                setScrollListenerForDividersVisibility(mContent);
             }
 
         }
@@ -329,6 +330,8 @@ public class MDRootLayout extends ViewGroup {
                 mButtons[INDEX_NEUTRAL].layout(bl, barTop, br, barBottom);
             }
         }
+
+        setUpDividersVisibility(mContent, true, false);
     }
 
     public void setForceStack(boolean forceStack) {
@@ -352,80 +355,92 @@ public class MDRootLayout extends ViewGroup {
         }
     }
 
-    private void setScrollListenerForDividersVisibility(View view) {
+    private void setUpDividersVisibility(View view, boolean topAndBottom, boolean bottom) {
         if (view == null)
             return;
         if (view instanceof ScrollView) {
             final ScrollView sv = (ScrollView) view;
-            if (mOnScrollChangedListener == null) {
-                mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
-                    @Override
-                    public void onScrollChanged() {
-                        boolean canScroll = canScrollViewScroll(sv);
-                        invalidateDividersVisibility(canScroll, sv);
-                    }
-                };
-                sv.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);
+            if (canScrollViewScroll(sv)) {
+                addScrollListener(sv, topAndBottom, bottom);
+            } else {
+                if (!bottom || topAndBottom)
+                    mDrawTopDivider = false;
+                if (bottom || topAndBottom)
+                    mDrawBottomDivider = false;
             }
         } else if (view instanceof AdapterView) {
             final AdapterView sv = (AdapterView) view;
-            if (mOnScrollChangedListener == null) {
-                mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
-                    @Override
-                    public void onScrollChanged() {
-                        boolean canScroll = canAdapterViewScroll(sv);
-                        invalidateDividersVisibility(canScroll, sv);
-                    }
-                };
-                sv.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);
+            if (canAdapterViewScroll(sv)) {
+                addScrollListener(sv, topAndBottom, bottom);
+            } else {
+                if (!bottom || topAndBottom)
+                    mDrawTopDivider = false;
+                if (bottom || topAndBottom)
+                    mDrawBottomDivider = false;
             }
         } else if (view instanceof WebView) {
             boolean canScroll = canWebViewScroll((WebView) view);
-            mDrawTopDivider = mDrawBottomDivider = canScroll;
+            if (!bottom || topAndBottom)
+                mDrawTopDivider = canScroll;
+            if (bottom || topAndBottom)
+                mDrawBottomDivider = canScroll;
         } else if (view instanceof RecyclerView) {
-            /* Scroll offset detection for RecyclerView isn't very reliable b/c the OnScrollChangedListener
+            /* Scroll offset detection for RecyclerView isn't reliable b/c the OnScrollChangedListener
             isn't always called on scroll. We can't set a OnScrollListener either because that will
             override the user's OnScrollListener if they set one.*/
-
-            final RecyclerView rv = (RecyclerView) view;
-            if (mOnScrollChangedListener == null) {
-                mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
-                    @Override
-                    public void onScrollChanged() {
-                        boolean canScroll = canRecyclerViewScroll(rv);
-                        invalidateDividersVisibility(canScroll, rv);
-                    }
-                };
-                rv.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);
-            }
+            boolean canScroll = canRecyclerViewScroll((RecyclerView) view);
+            if (!bottom || topAndBottom)
+                mDrawTopDivider = canScroll;
+            if (bottom || topAndBottom)
+                mDrawBottomDivider = canScroll;
         } else if (view instanceof ViewGroup) {
-            View bottomView = getBottomView((ViewGroup) view);
-            setScrollListenerForDividersVisibility(bottomView);
             View topView = getTopView((ViewGroup) view);
-            setScrollListenerForDividersVisibility(topView);
+            setUpDividersVisibility(topView, topAndBottom, false);
+            View bottomView = getBottomView((ViewGroup) view);
+            if (bottomView != topView) {
+                setUpDividersVisibility(bottomView, false, true);
+            }
         }
     }
 
-    private void invalidateDividersVisibility(boolean canScroll, ViewGroup view) {
-        if (canScroll) {
-            boolean hasButtons = false;
-            for (MDButton button : mButtons) {
-                if (button != null && button.getVisibility() != View.GONE) {
-                    hasButtons = true;
+    private void addScrollListener(final ViewGroup vg, final boolean topAndBottom, final boolean bottom) {
+        if ((!bottom && mTopOnScrollChangedListener == null
+                || (bottom && mBottomOnScrollChangedListener == null))) {
+            ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
+                @Override
+                public void onScrollChanged() {
+                    invalidateDividersForScrollingView(vg, topAndBottom, bottom);
                 }
+            };
+            if (!bottom) {
+                mTopOnScrollChangedListener = onScrollChangedListener;
+                vg.getViewTreeObserver().addOnScrollChangedListener(mTopOnScrollChangedListener);
+            } else {
+                mBottomOnScrollChangedListener = onScrollChangedListener;
+                vg.getViewTreeObserver().addOnScrollChangedListener(mBottomOnScrollChangedListener);
             }
+        }
+    }
 
-            mDrawTopDivider =
-                    mTitleBar != null &&
-                            mTitleBar.getVisibility() != View.GONE &&
-                            //Not scrolled to the top.
-                            view.getScrollY() + view.getPaddingTop() > view.getChildAt(0).getTop();
+    private void invalidateDividersForScrollingView(ViewGroup view, final boolean topAndBottom, boolean bottom) {
+        boolean hasButtons = false;
+        for (MDButton button : mButtons) {
+            if (button != null && button.getVisibility() != View.GONE) {
+                hasButtons = true;
+            }
+        }
+        if (!bottom || topAndBottom) {
+            mDrawTopDivider = mTitleBar != null &&
+                    mTitleBar.getVisibility() != View.GONE &&
+                    //Not scrolled to the top.
+                    view.getScrollY() + view.getPaddingTop() > view.getChildAt(0).getTop();
 
-            mDrawBottomDivider =
-                    hasButtons &&
-                            view.getScrollY() + view.getHeight() - view.getPaddingBottom() < view.getChildAt(view.getChildCount() - 1).getBottom();
-            invalidate();
         }
+        if (bottom || topAndBottom) {
+            mDrawBottomDivider = hasButtons &&
+                    view.getScrollY() + view.getHeight() - view.getPaddingBottom() < view.getChildAt(view.getChildCount() - 1).getBottom();
+        }
+        invalidate();
     }
 
     public static boolean canRecyclerViewScroll(RecyclerView view) {
@@ -484,7 +499,7 @@ public class MDRootLayout extends ViewGroup {
      * however getChildDrawingOrder is not taking into account for simplicity and because it behaves
      * inconsistently across platform versions.
      *
-     * @return View touching the bottom of this viewgroup or null
+     * @return View touching the bottom of this ViewGroup or null
      */
     @Nullable
     private static View getBottomView(ViewGroup viewGroup) {

+ 2 - 2
library/src/main/res/values/dimens.xml

@@ -39,7 +39,7 @@
 
     <dimen name="md_content_padding_top">8dp</dimen>
 
-    <dimen name="md_button_min_width">64dp</dimen>
+    <dimen name="md_button_min_width">72dp</dimen>
     <!-- Above and below buttons, 36+6+6=48 for the height of the button frame -->
     <dimen name="md_button_inset_vertical">6dp</dimen>
     <dimen name="md_button_inset_horizontal">4dp</dimen>
@@ -55,7 +55,7 @@
     <dimen name="md_content_padding_bottom">8dp</dimen>
     <dimen name="md_button_frame_vertical_padding">8dp</dimen>
     <dimen name="md_button_height">48dp</dimen>
-    <dimen name="md_title_textsize">18sp</dimen>
+    <dimen name="md_title_textsize">20sp</dimen>
     <dimen name="md_content_textsize">16sp</dimen>
     <dimen name="md_button_textsize">14sp</dimen>
     <dimen name="md_listitem_textsize">16sp</dimen>