Bläddra i källkod

Restore OutLineProvider.

zhpanvip 3 år sedan
förälder
incheckning
f046594716

+ 2 - 1
app/src/main/java/com/example/zhpan/banner/fragment/OthersFragment.java

@@ -99,6 +99,7 @@ public class OthersFragment extends BaseFragment implements View.OnClickListener
       } else if (checkedId == R.id.rb_vector_drawable) {
         setDrawableIndicator(getVectorDrawableIndicator());
       } else if (checkedId == R.id.rb_round_corner) {
+        mViewPager.setRoundCorner(1);
         setRoundCorner();
       }
     });
@@ -109,7 +110,7 @@ public class OthersFragment extends BaseFragment implements View.OnClickListener
     int dp36 = getResources().getDimensionPixelOffset(R.dimen.dp_36);
     mViewPager
         .setRoundCorner(dp36, 0, 0, dp36)
-        .refreshData(getPicList(4));
+        .create(getPicList(4));
   }
 
   private void setDrawableIndicator(IIndicator indicator) {

+ 1 - 1
app/src/main/res/layout/fragment_others.xml

@@ -92,7 +92,7 @@
             android:layout_height="wrap_content"
             android:layout_marginBottom="@dimen/dp_10"
             android:layout_marginEnd="15dp"
-            android:text="Round Corner"
+            android:text="Top Left Bottom Right Round Corner"
             android:textSize="@dimen/sp_16" />
 
       </RadioGroup>

+ 43 - 5
bannerview/src/main/java/com/zhpan/bannerview/BannerViewPager.java

@@ -2,8 +2,12 @@ package com.zhpan.bannerview;
 
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.RectF;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Parcelable;
@@ -28,6 +32,7 @@ import com.zhpan.bannerview.constants.PageStyle;
 import com.zhpan.bannerview.manager.BannerManager;
 import com.zhpan.bannerview.manager.BannerOptions;
 import com.zhpan.bannerview.provider.ReflectLayoutManager;
+import com.zhpan.bannerview.provider.ViewStyleSetter;
 import com.zhpan.bannerview.utils.BannerUtils;
 import com.zhpan.indicator.IndicatorView;
 import com.zhpan.indicator.annotation.AIndicatorSlideMode;
@@ -83,8 +88,8 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
   };
 
   private RectF mRadiusRectF;
-
   private Path mRadiusPath;
+  private Paint mPaint;
 
   private int startX, startY;
 
@@ -298,6 +303,7 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
     if (list != null) {
       setIndicatorValues(list);
       setupViewPager(list);
+      initRoundCorner();
     }
   }
 
@@ -360,13 +366,27 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
     if (mRadiusRectF != null && mRadiusPath != null) {
       mRadiusRectF.right = this.getWidth();
       mRadiusRectF.bottom = this.getHeight();
-      mRadiusPath.addRoundRect(mRadiusRectF, mBannerManager.getBannerOptions().getRoundRectRadius(),
+      mRadiusPath.addRoundRect(mRadiusRectF,
+          mBannerManager.getBannerOptions().getRoundRectRadiusArray(),
           Path.Direction.CW);
-      canvas.clipPath(mRadiusPath);
+      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+        canvas.clipPath(mRadiusPath);
+      } else {
+        if (mPaint != null) {
+          canvas.drawPath(mRadiusPath, mPaint);
+        }
+      }
     }
     super.dispatchDraw(canvas);
   }
 
+  private void initRoundCorner() {
+    int roundCorner = mBannerManager.getBannerOptions().getRoundRectRadius();
+    if (roundCorner > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+      ViewStyleSetter.applyRoundCorner(this, roundCorner);
+    }
+  }
+
   private void setupViewPager(List<T> list) {
     if (mBannerPagerAdapter == null) {
       throw new NullPointerException("You must set adapter for BannerViewPager");
@@ -521,7 +541,8 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
    * @param radius round radius
    */
   public BannerViewPager<T> setRoundCorner(int radius) {
-    return setRoundCorner(radius, radius, radius, radius);
+    mBannerManager.getBannerOptions().setRoundRectRadius(radius);
+    return this;
   }
 
   /**
@@ -537,6 +558,10 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
       int bottomRightRadius) {
     mRadiusRectF = new RectF();
     mRadiusPath = new Path();
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+      mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
+    }
     mBannerManager.getBannerOptions()
         .setRoundRectRadius(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
     return this;
@@ -551,6 +576,20 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
     return setRoundCorner(radius);
   }
 
+  /**
+   * Set round rectangle effect for BannerViewPager.
+   *
+   * @param topLeftRadius top left round radius
+   * @param topRightRadius top right round radius
+   * @param bottomLeftRadius bottom left round radius
+   * @param bottomRightRadius bottom right round radius
+   */
+  public BannerViewPager<T> setRoundRect(int topLeftRadius, int topRightRadius,
+      int bottomLeftRadius,
+      int bottomRightRadius) {
+    return setRoundCorner(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+  }
+
   /**
    * Enable/disable auto play
    *
@@ -1105,7 +1144,6 @@ public class BannerViewPager<T> extends RelativeLayout implements LifecycleObser
   }
 
   /**
-   *
    * @param showIndicatorWhenOneItem 只有一个item时是否显示指示器,
    * true:显示,false:不显示,默认值false
    */

+ 19 - 17
bannerview/src/main/java/com/zhpan/bannerview/manager/BannerOptions.java

@@ -1,7 +1,5 @@
 package com.zhpan.bannerview.manager;
 
-import android.graphics.Path;
-import android.graphics.RectF;
 import android.view.View;
 
 import androidx.viewpager2.widget.ViewPager2;
@@ -11,8 +9,6 @@ import com.zhpan.bannerview.utils.BannerUtils;
 import com.zhpan.indicator.enums.IndicatorOrientation;
 import com.zhpan.indicator.option.IndicatorOptions;
 
-import java.util.Arrays;
-
 import static com.zhpan.bannerview.transform.ScaleInTransformer.DEFAULT_MIN_SCALE;
 
 /**
@@ -29,7 +25,6 @@ public class BannerOptions {
     pageMargin = BannerUtils.dp2px(20);
     rightRevealWidth = DEFAULT_REVEAL_WIDTH;
     leftRevealWidth = DEFAULT_REVEAL_WIDTH;
-    roundRadius = new float[8];
   }
 
   public static final int DEFAULT_REVEAL_WIDTH = -1000;
@@ -60,7 +55,9 @@ public class BannerOptions {
 
   private int scrollDuration;
 
-  private float[] roundRadius;
+  private float[] roundRadiusArray;
+
+  private int roundRadius;
 
   private boolean userInputEnabled = true;
 
@@ -126,7 +123,7 @@ public class BannerOptions {
     mIndicatorOptions.setSliderWidth(normalWidth, checkedWidth);
   }
 
-  public void showIndicatorWhenOnItem(boolean showIndicatorWhenOneItem){
+  public void showIndicatorWhenOnItem(boolean showIndicatorWhenOneItem) {
     mIndicatorOptions.setShowIndicatorOneItem(showIndicatorWhenOneItem);
   }
 
@@ -218,24 +215,29 @@ public class BannerOptions {
     mIndicatorMargin = new IndicatorMargin(left, top, right, bottom);
   }
 
-  public float[] getRoundRectRadius() {
+  public float[] getRoundRectRadiusArray() {
+    return roundRadiusArray;
+  }
+
+  public int getRoundRectRadius() {
     return roundRadius;
   }
 
   public void setRoundRectRadius(int radius) {
-    setRoundRectRadius(radius, radius, radius, radius);
+    this.roundRadius = radius;
   }
 
   public void setRoundRectRadius(int topLeftRadius, int topRightRadius, int bottomLeftRadius,
       int bottomRightRadius) {
-    roundRadius[0] = topLeftRadius;
-    roundRadius[1] = topLeftRadius;
-    roundRadius[2] = topRightRadius;
-    roundRadius[3] = topRightRadius;
-    roundRadius[4] = bottomRightRadius;
-    roundRadius[5] = bottomRightRadius;
-    roundRadius[6] = bottomLeftRadius;
-    roundRadius[7] = bottomLeftRadius;
+    roundRadiusArray = new float[8];
+    roundRadiusArray[0] = topLeftRadius;
+    roundRadiusArray[1] = topLeftRadius;
+    roundRadiusArray[2] = topRightRadius;
+    roundRadiusArray[3] = topRightRadius;
+    roundRadiusArray[4] = bottomRightRadius;
+    roundRadiusArray[5] = bottomRightRadius;
+    roundRadiusArray[6] = bottomLeftRadius;
+    roundRadiusArray[7] = bottomLeftRadius;
   }
 
   public int getScrollDuration() {

+ 60 - 0
bannerview/src/main/java/com/zhpan/bannerview/provider/OvalViewOutlineProvider.java

@@ -0,0 +1,60 @@
+
+package com.zhpan.bannerview.provider;
+
+import android.annotation.TargetApi;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+/**
+ * <pre>
+ *   Created by zhangpan on 2018/12/26.
+ *   Description:圆形效果
+ * </pre>
+ */
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class OvalViewOutlineProvider extends ViewOutlineProvider {
+
+
+    public OvalViewOutlineProvider() {}
+
+    @Override
+    public void getOutline(final View view, final Outline outline) {
+        Rect ovalRect = convertToCircleRect(new Rect(0, 0, view.getWidth(), view.getHeight()));
+        outline.setOval(ovalRect);
+    }
+
+    /**
+     * 以矩形的中心点为圆心,较短的边为直径画圆
+     *
+     * 注意, 由于整除省略了小数, (x/2)*2不一定等于x
+     * 
+     * Currently, only Outlines that can be represented as a rectangle, circle, or round rect
+     * support clipping.
+     * 
+     * @param rect
+     * @return
+     */
+    private Rect convertToCircleRect(Rect rect) {
+        int left, top, right, bottom;
+        if(rect.width() > rect.height()) {
+            int dH = rect.height() / 2;
+            left = rect.centerX() - dH;
+            top = 0;
+            right = rect.centerX() + dH;
+            bottom = dH * 2;
+        } else {
+            int dW = rect.width() / 2;
+            left = 0;
+            top = rect.centerY() - dW;
+            right = dW * 2;
+            bottom = rect.centerY() + dW;
+        }
+        rect.set(left, top, right, bottom);
+        return rect;
+    }
+
+}

+ 33 - 0
bannerview/src/main/java/com/zhpan/bannerview/provider/RoundViewOutlineProvider.java

@@ -0,0 +1,33 @@
+
+
+package com.zhpan.bannerview.provider;
+
+import android.annotation.TargetApi;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+/**
+ * <pre>
+ *   Created by zhangpan on 2018/12/26.
+ *   Description:圆角效果
+ * </pre>
+ */
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class RoundViewOutlineProvider extends ViewOutlineProvider {
+
+    private float mRadius;// 圆角弧度
+
+    public RoundViewOutlineProvider(float radius) {
+        this.mRadius = radius;
+    }
+
+    @Override
+    public void getOutline(View view, Outline outline) {
+        Rect selfRect = new Rect(0, 0, view.getWidth(), view.getHeight());// 绘制区域
+        outline.setRoundRect(selfRect, mRadius);
+    }
+}

+ 56 - 0
bannerview/src/main/java/com/zhpan/bannerview/provider/ViewStyleSetter.java

@@ -0,0 +1,56 @@
+
+
+package com.zhpan.bannerview.provider;
+
+import android.os.Build;
+import android.view.View;
+import androidx.annotation.RequiresApi;
+
+/**
+ * <pre>
+ *   Created by zhangpan on 2018/12/26.
+ *   Description:为View设置圆角/圆形效果,支持View及ViewGroup,适用Android 5.1及以上系统。
+ * </pre>
+ */
+
+public class ViewStyleSetter {
+
+    private ViewStyleSetter() {}
+
+    /**
+     * 为View设置圆角效果
+     * 
+     * @param radius 圆角半径
+     */
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    public static void applyRoundCorner(View target, float radius) {
+        if(target == null) {
+            return;
+        }
+        target.setClipToOutline(true);// 用outline裁剪内容区域
+        target.setOutlineProvider(new RoundViewOutlineProvider(radius));
+    }
+
+    /**
+     * 设置View为圆形
+     */
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    public static void applyCircle(View target) {
+        if(target == null) {
+            return;
+        }
+        target.setClipToOutline(true);// 用outline裁剪内容区域
+        target.setOutlineProvider(new OvalViewOutlineProvider());
+    }
+
+    /**
+     * 清除View的圆角效果
+     */
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    public static void clearShapeStyle(View target) {
+        if(target == null) {
+            return;
+        }
+        target.setClipToOutline(false);
+    }
+}