Browse Source

Add divider visibility detection to WebView

plusCubed 10 năm trước cách đây
mục cha
commit
07fcfe8b61

+ 71 - 36
library/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java

@@ -21,6 +21,7 @@ import android.widget.ScrollView;
 import com.afollestad.materialdialogs.GravityEnum;
 import com.afollestad.materialdialogs.MaterialDialog;
 import com.afollestad.materialdialogs.R;
+import com.afollestad.materialdialogs.util.DialogUtils;
 
 /**
  * @author Kevin Barry (teslacoil) 4/02/2015
@@ -60,6 +61,7 @@ public class MDRootLayout extends ViewGroup {
 
     private ViewTreeObserver.OnScrollChangedListener mTopOnScrollChangedListener;
     private ViewTreeObserver.OnScrollChangedListener mBottomOnScrollChangedListener;
+    private int mDividerWidth;
 
     public MDRootLayout(Context context) {
         super(context);
@@ -97,8 +99,8 @@ public class MDRootLayout extends ViewGroup {
         mButtonBarHeight = r.getDimensionPixelSize(R.dimen.md_button_height);
 
         mDividerPaint = new Paint();
-        mDividerPaint.setStrokeWidth(r.getDimensionPixelSize(R.dimen.md_divider_height));
-        mDividerPaint.setStyle(Paint.Style.STROKE);
+        mDividerWidth = r.getDimensionPixelSize(R.dimen.md_divider_height);
+        mDividerPaint.setColor(DialogUtils.resolveColor(context, R.attr.md_divider_color));
         setWillNotDraw(false);
     }
 
@@ -224,12 +226,12 @@ public class MDRootLayout extends ViewGroup {
         if (mContent != null) {
             if (mDrawTopDivider) {
                 int y = mContent.getTop();
-                canvas.drawLine(0, y, getMeasuredWidth(), y, mDividerPaint);
+                canvas.drawRect(0, y - mDividerWidth, getMeasuredWidth(), y, mDividerPaint);
             }
 
             if (mDrawBottomDivider) {
                 int y = mContent.getBottom();
-                canvas.drawLine(0, y, getMeasuredWidth(), y, mDividerPaint);
+                canvas.drawRect(0, y, getMeasuredWidth(), y + mDividerWidth, mDividerPaint);
             }
         }
     }
@@ -333,7 +335,7 @@ public class MDRootLayout extends ViewGroup {
             }
         }
 
-        setUpDividersVisibility(mContent, true, false);
+        setUpDividersVisibility(mContent, true, true);
     }
 
     public void setForceStack(boolean forceStack) {
@@ -357,47 +359,59 @@ public class MDRootLayout extends ViewGroup {
         }
     }
 
-    private void setUpDividersVisibility(View view, boolean topAndBottom, boolean bottom) {
+    private void setUpDividersVisibility(final View view, final boolean setForTop, final boolean setForBottom) {
         if (view == null)
             return;
         if (view instanceof ScrollView) {
             final ScrollView sv = (ScrollView) view;
             if (canScrollViewScroll(sv)) {
-                addScrollListener(sv, topAndBottom, bottom);
+                addScrollListener(sv, setForTop, setForBottom);
             } else {
-                if (!bottom || topAndBottom)
+                if (setForTop)
                     mDrawTopDivider = false;
-                if (bottom || topAndBottom)
+                if (setForBottom)
                     mDrawBottomDivider = false;
             }
         } else if (view instanceof AdapterView) {
             final AdapterView sv = (AdapterView) view;
             if (canAdapterViewScroll(sv)) {
-                addScrollListener(sv, topAndBottom, bottom);
+                addScrollListener(sv, setForTop, setForBottom);
             } else {
-                if (!bottom || topAndBottom)
+                if (setForTop)
                     mDrawTopDivider = false;
-                if (bottom || topAndBottom)
+                if (setForBottom)
                     mDrawBottomDivider = false;
             }
         } else if (view instanceof WebView) {
-            boolean canScroll = canWebViewScroll((WebView) view);
-            if (!bottom || topAndBottom)
-                mDrawTopDivider = canScroll;
-            if (bottom || topAndBottom)
-                mDrawBottomDivider = canScroll;
+            view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    if (view.getMeasuredHeight() != 0) {
+                        if (!canWebViewScroll((WebView) view)) {
+                            if (setForTop)
+                                mDrawTopDivider = false;
+                            if (setForBottom)
+                                mDrawBottomDivider = false;
+                        } else {
+                            addScrollListener((ViewGroup) view, setForTop, setForBottom);
+                        }
+                        view.getViewTreeObserver().removeOnPreDrawListener(this);
+                    }
+                    return true;
+                }
+            });
         } else if (view instanceof RecyclerView) {
             /* 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.*/
             boolean canScroll = canRecyclerViewScroll((RecyclerView) view);
-            if (!bottom || topAndBottom)
+            if (setForTop)
                 mDrawTopDivider = canScroll;
-            if (bottom || topAndBottom)
+            if (setForBottom)
                 mDrawBottomDivider = canScroll;
         } else if (view instanceof ViewGroup) {
             View topView = getTopView((ViewGroup) view);
-            setUpDividersVisibility(topView, topAndBottom, bottom);
+            setUpDividersVisibility(topView, setForTop, setForBottom);
             View bottomView = getBottomView((ViewGroup) view);
             if (bottomView != topView) {
                 setUpDividersVisibility(bottomView, false, true);
@@ -405,44 +419,64 @@ public class MDRootLayout extends ViewGroup {
         }
     }
 
-    private void addScrollListener(final ViewGroup vg, final boolean topAndBottom, final boolean bottom) {
-        if ((!bottom && mTopOnScrollChangedListener == null
-                || (bottom && mBottomOnScrollChangedListener == null))) {
+    private void addScrollListener(final ViewGroup vg, final boolean setForTop, final boolean setForBottom) {
+        if ((!setForBottom && mTopOnScrollChangedListener == null
+                || (setForBottom && mBottomOnScrollChangedListener == null))) {
             ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
                 @Override
                 public void onScrollChanged() {
-                    invalidateDividersForScrollingView(vg, topAndBottom, bottom);
+                    boolean hasButtons = false;
+                    for (MDButton button : mButtons) {
+                        if (button != null && button.getVisibility() != View.GONE) {
+                            hasButtons = true;
+                            break;
+                        }
+                    }
+                    if (vg instanceof WebView) {
+                        invalidateDividersForWebView((WebView) vg, setForTop, setForBottom, hasButtons);
+                    } else {
+                        invalidateDividersForScrollingView(vg, setForTop, setForBottom, hasButtons);
+                    }
+                    invalidate();
                 }
             };
-            if (!bottom) {
+            if (!setForBottom) {
                 mTopOnScrollChangedListener = onScrollChangedListener;
                 vg.getViewTreeObserver().addOnScrollChangedListener(mTopOnScrollChangedListener);
             } else {
                 mBottomOnScrollChangedListener = onScrollChangedListener;
                 vg.getViewTreeObserver().addOnScrollChangedListener(mBottomOnScrollChangedListener);
             }
+            onScrollChangedListener.onScrollChanged();
         }
     }
 
-    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) && view.getChildCount() > 0) {
+    private void invalidateDividersForScrollingView(ViewGroup view, final boolean setForTop, boolean setForBottom, boolean hasButtons) {
+        if (setForTop && view.getChildCount() > 0) {
             mDrawTopDivider = mTitleBar != null &&
                     mTitleBar.getVisibility() != View.GONE &&
                     //Not scrolled to the top.
                     view.getScrollY() + view.getPaddingTop() > view.getChildAt(0).getTop();
 
         }
-        if ((bottom || topAndBottom) && view.getChildCount() > 0) {
+        if (setForBottom && view.getChildCount() > 0) {
             mDrawBottomDivider = hasButtons &&
                     view.getScrollY() + view.getHeight() - view.getPaddingBottom() < view.getChildAt(view.getChildCount() - 1).getBottom();
         }
-        invalidate();
+    }
+
+    private void invalidateDividersForWebView(WebView view, final boolean setForTop, boolean setForBottom, boolean hasButtons) {
+        if (setForTop) {
+            mDrawTopDivider = mTitleBar != null &&
+                    mTitleBar.getVisibility() != View.GONE &&
+                    //Not scrolled to the top.
+                    view.getScrollY() + view.getPaddingTop() > 0;
+        }
+        if (setForBottom) {
+            //noinspection deprecation
+            mDrawBottomDivider = hasButtons &&
+                    view.getScrollY() + view.getMeasuredHeight() - view.getPaddingBottom() < view.getContentHeight() * view.getScale();
+        }
     }
 
     public static boolean canRecyclerViewScroll(RecyclerView view) {
@@ -473,7 +507,8 @@ public class MDRootLayout extends ViewGroup {
     }
 
     private static boolean canWebViewScroll(WebView view) {
-        return view.getMeasuredHeight() > view.getContentHeight();
+        //noinspection deprecation
+        return view.getMeasuredHeight() < view.getContentHeight() * view.getScale();
     }
 
     private static boolean canAdapterViewScroll(AdapterView lv) {