diff --git a/app/build.gradle b/app/build.gradle index d1b575b..c708fc6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation 'com.zhy:magic-viewpager:1.0.1' implementation 'com.github.lihangleo2:ShadowLayout:2.1.5' implementation 'com.blankj:utilcode:1.25.9' + api 'com.romandanylyk:pageindicatorview:1.0.2' implementation project(":banner") diff --git a/app/src/main/java/com/to/aboomy/bannersample/activity/Indicator2Activity.java b/app/src/main/java/com/to/aboomy/bannersample/activity/Indicator2Activity.java index f26a5f7..31123ac 100644 --- a/app/src/main/java/com/to/aboomy/bannersample/activity/Indicator2Activity.java +++ b/app/src/main/java/com/to/aboomy/bannersample/activity/Indicator2Activity.java @@ -5,17 +5,22 @@ import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; +import android.view.ViewGroup; +import android.widget.RelativeLayout; import android.widget.TextView; +import com.blankj.utilcode.util.SizeUtils; +import com.rd.PageIndicatorView; +import com.rd.animation.type.AnimationType; import com.to.aboomy.banner.Banner; import com.to.aboomy.banner.Indicator; import com.to.aboomy.banner.IndicatorView; import com.to.aboomy.bannersample.R; import com.to.aboomy.bannersample.creator.ImageTest1ChildHolderCreator; -import com.to.aboomy.bannersample.indicator.LineIndicatorView; import com.to.aboomy.bannersample.indicator.CircleIndicatorView; import com.to.aboomy.bannersample.indicator.DashPointView; import com.to.aboomy.bannersample.indicator.DashReverseView; +import com.to.aboomy.bannersample.indicator.LineIndicatorView; import com.to.aboomy.bannersample.indicator.LinePagerTitleIndicatorView; import com.to.aboomy.bannersample.util.ArrayStringItemSelectDialog; import com.to.aboomy.bannersample.util.Utils; @@ -32,11 +37,14 @@ public class Indicator2Activity extends AppCompatActivity { "CircleIndicatorView", "CircleIndicatorView-FollowTouch", "LinePagerTitleIndicatorView", - "LineIndicatorView" + "LineIndicatorView", + "PageIndicatorView-FILL", + "PageIndicatorView-THIN_WORM", + "PageIndicatorView-DROP", + "PageIndicatorView-SWAP", }; private int choose; - @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -67,10 +75,8 @@ public void onItemClick(int position, String value) { }).show(); } }); - } - public Indicator getIndicator(int position) { switch (position) { case 0: @@ -78,20 +84,78 @@ public Indicator getIndicator(int position) { case 1: return new DashReverseView(this); case 2: - CircleIndicatorView c = new CircleIndicatorView(this); - c.setCircleColor(Color.WHITE); - c.setFollowTouch(false); - return c; + return getCircleIndicatorView(false); case 3: - CircleIndicatorView c1 = new CircleIndicatorView(this); - c1.setCircleColor(Color.WHITE); - return c1; + return getCircleIndicatorView(true); case 4: return new LinePagerTitleIndicatorView(this); case 5: return new LineIndicatorView(this); + case 6: + return getPageIndicatorView(AnimationType.FILL); + case 7: + return getPageIndicatorView(AnimationType.THIN_WORM); + case 8: + return getPageIndicatorView(AnimationType.DROP); + case 9: + return getPageIndicatorView(AnimationType.SWAP); default: return new IndicatorView(this); } } + + private CircleIndicatorView getCircleIndicatorView(boolean followTouch){ + CircleIndicatorView circleIndicatorView = new CircleIndicatorView(this); + circleIndicatorView.setCircleColor(Color.RED); + circleIndicatorView.setFollowTouch(followTouch); + return circleIndicatorView; + } + + /** + * 集成 https://github.com/romandanylyk/PageIndicatorView + */ + private Indicator getPageIndicatorView(AnimationType type) { + final PageIndicatorView pageIndicatorView = new PageIndicatorView(this); + pageIndicatorView.setAnimationType(type); + pageIndicatorView.setInteractiveAnimation(true); + pageIndicatorView.setSelectedColor(Color.RED); + pageIndicatorView.setUnselectedColor(Color.GRAY); + pageIndicatorView.setPadding(10); + pageIndicatorView.setRadius(8); + return new Indicator() { + @Override + public void onPageScrolled(int i, float v, int i1) { + + } + + @Override + public void onPageSelected(int position) { + pageIndicatorView.setSelection(position); + } + + @Override + public void onPageScrollStateChanged(int i) { + + } + + @Override + public void initIndicatorCount(int pagerCount) { + pageIndicatorView.setCount(pagerCount); + } + + @Override + public View getView() { + return pageIndicatorView; + } + + @Override + public RelativeLayout.LayoutParams getParams() { + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + params.addRule(RelativeLayout.CENTER_HORIZONTAL); + params.bottomMargin = SizeUtils.dp2px(20); + return params; + } + }; + } } diff --git a/app/src/main/java/com/to/aboomy/bannersample/activity/MainActivity.java b/app/src/main/java/com/to/aboomy/bannersample/activity/MainActivity.java index 5c99fcf..cc22965 100644 --- a/app/src/main/java/com/to/aboomy/bannersample/activity/MainActivity.java +++ b/app/src/main/java/com/to/aboomy/bannersample/activity/MainActivity.java @@ -54,6 +54,10 @@ protected void onCreate(Bundle savedInstanceState) { list.add(Utils.getRandom()); banner = findViewById(R.id.banner); final IndicatorView indicatorView = new IndicatorView(this) +// .setIndicatorRatio(1.5f) +// .setIndicatorSelectedRadius(4) + .setIndicatorRadius(5.5f) +// .setIndicatorStyle(IndicatorView.IndicatorStyle.INDICATOR_BEZIER) .setIndicatorColor(Color.GRAY) .setIndicatorSelectorColor(Color.WHITE); banner.setIndicator(indicatorView) diff --git a/app/src/main/java/com/to/aboomy/bannersample/creator/ImageHolderCreator.java b/app/src/main/java/com/to/aboomy/bannersample/creator/ImageHolderCreator.java index 1c8b41a..38887bd 100644 --- a/app/src/main/java/com/to/aboomy/bannersample/creator/ImageHolderCreator.java +++ b/app/src/main/java/com/to/aboomy/bannersample/creator/ImageHolderCreator.java @@ -2,7 +2,6 @@ import android.content.Context; import android.support.annotation.NonNull; -import android.util.Log; import android.view.View; import android.widget.ImageView; @@ -18,7 +17,6 @@ public class ImageHolderCreator implements HolderCreator { @NonNull @Override public View createView(final Context context, final int index, Object o) { - Log.e("aa", "index " + index); ImageView iv = new ImageView(context); iv.setScaleType(ImageView.ScaleType.FIT_XY); Glide.with(iv).load(o).into(iv); diff --git a/app/src/main/java/com/to/aboomy/bannersample/indicator/DashPointView.java b/app/src/main/java/com/to/aboomy/bannersample/indicator/DashPointView.java index 5650b0e..dd35eff 100644 --- a/app/src/main/java/com/to/aboomy/bannersample/indicator/DashPointView.java +++ b/app/src/main/java/com/to/aboomy/bannersample/indicator/DashPointView.java @@ -18,7 +18,7 @@ public class DashPointView extends LinearLayout implements Indicator { private int pointRadius = dip2px(3); - private int pointSelectColor = Color.WHITE; + private int pointSelectColor = Color.RED; private int pointColor = Color.GRAY; private int maxPointWidth = pointRadius * 6; private int pointWidth = pointRadius * 2; diff --git a/app/src/main/java/com/to/aboomy/bannersample/indicator/DashReverseView.java b/app/src/main/java/com/to/aboomy/bannersample/indicator/DashReverseView.java index b1d96f3..fe0d80f 100644 --- a/app/src/main/java/com/to/aboomy/bannersample/indicator/DashReverseView.java +++ b/app/src/main/java/com/to/aboomy/bannersample/indicator/DashReverseView.java @@ -18,7 +18,7 @@ public class DashReverseView extends LinearLayout implements Indicator { private int pointRadius = dip2px(2); - private int pointSelectColor = Color.WHITE; + private int pointSelectColor = Color.RED; private int pointColor = Color.GRAY; private int pointWidth = pointRadius * 6; private int pointHeight = pointRadius * 2; diff --git a/banner/src/main/java/com/to/aboomy/banner/IndicatorView.java b/banner/src/main/java/com/to/aboomy/banner/IndicatorView.java index 7e22c6f..b5a905d 100644 --- a/banner/src/main/java/com/to/aboomy/banner/IndicatorView.java +++ b/banner/src/main/java/com/to/aboomy/banner/IndicatorView.java @@ -2,6 +2,7 @@ import android.content.Context; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; @@ -23,25 +24,32 @@ public class IndicatorView extends View implements Indicator { private final Interpolator interpolator = new DecelerateInterpolator(); private Interpolator accelerateInterpolator; - private RectF selectorRect; + private Path path; private float offset; private int selectedPage; private int pagerCount; + private int unColor = Color.GRAY; + private int selectedColor = Color.WHITE; - private final Paint selectedIndicatorPaint; private final Paint indicatorPaint; + private final RectF rectF; /** * 控制在banner中的位置 */ private RelativeLayout.LayoutParams params; /** - * indicator样式 目前支持三种样式 + * indicator样式 */ private int indicatorStyle; + /*--------------- 核心控制点大小距离参数 ---------------*/ private float indicatorRadius = dip2px(3.5f); + private float indicatorRatio = 1.0f; + private float indicatorSelectedRadius = dip2px(3.5f); + private float indicatorSelectedRatio = 1.0f; private float indicatorSpacing = dip2px(10); + /*--------------- 核心控制点大小距离参数end ---------------*/ @IntDef({IndicatorStyle.INDICATOR_CIRCLE, IndicatorStyle.INDICATOR_CIRCLE_RECT, @@ -67,40 +75,10 @@ public IndicatorView(Context context, @Nullable AttributeSet attrs) { public IndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - selectedIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + rectF = new RectF(); indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); } - public IndicatorView setIndicatorRadius(float indicatorRadius) { - this.indicatorRadius = indicatorRadius; - return this; - } - - public IndicatorView setIndicatorSpacing(float indicatorSpacing) { - this.indicatorSpacing = indicatorSpacing; - return this; - } - - public IndicatorView setIndicatorStyle(@IndicatorStyle int indicatorStyle) { - this.indicatorStyle = indicatorStyle; - return this; - } - - public IndicatorView setIndicatorColor(@ColorInt int indicatorColor) { - this.indicatorPaint.setColor(indicatorColor); - return this; - } - - public IndicatorView setIndicatorSelectorColor(@ColorInt int indicatorSelectorColor) { - this.selectedIndicatorPaint.setColor(indicatorSelectorColor); - return this; - } - - public IndicatorView setParams(RelativeLayout.LayoutParams params) { - this.params = params; - return this; - } - @Override public void initIndicatorCount(int pagerCount) { this.pagerCount = pagerCount; @@ -124,6 +102,23 @@ public RelativeLayout.LayoutParams getParams() { return params; } + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + selectedPage = position; + offset = positionOffset; + invalidate(); + } + + @Override + public void onPageSelected(int position) { + + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -140,7 +135,7 @@ private int measureWidth(int widthMeasureSpec) { break; case MeasureSpec.AT_MOST: case MeasureSpec.UNSPECIFIED: - result = (int) (pagerCount * indicatorRadius * 2 + (pagerCount - 1) * indicatorSpacing + getPaddingLeft() + getPaddingRight()); + result = (int) (pagerCount * Math.max(indicatorRadius, indicatorSelectedRadius) * indicatorRatio * 2 + (pagerCount - 1) * indicatorSpacing + getPaddingLeft() + getPaddingRight()); break; default: break; @@ -158,7 +153,7 @@ private int measureHeight(int heightMeasureSpec) { break; case MeasureSpec.AT_MOST: case MeasureSpec.UNSPECIFIED: - result = (int) (indicatorRadius * 2 + getPaddingTop() + getPaddingBottom()); + result = (int) (Math.max(indicatorRadius, indicatorSelectedRadius) * 2 + getPaddingTop() + getPaddingBottom()); break; default: break; @@ -190,28 +185,39 @@ private void drawCircle(Canvas canvas, float midY) { drawPagerCountCircle(canvas, midY); float indicatorStartX = indicatorStartX(selectedPage); float nextIndicatorStartX = indicatorStartX((selectedPage + 1) % pagerCount); - float indicatorX = indicatorStartX + (nextIndicatorStartX - indicatorStartX) * interpolatedOffset(); - canvas.drawCircle(indicatorX, midY, indicatorRadius, selectedIndicatorPaint); + float ratioRadius = getRatioSelectedRadius(); + float left = indicatorStartX - ratioRadius; + float right = indicatorStartX + ratioRadius; + float nextLeft = nextIndicatorStartX - ratioRadius; + float nextRight = nextIndicatorStartX + ratioRadius; + float leftX = left + (nextLeft - left) * interpolatedOffset(); + float rightX = right + (nextRight - right) * interpolatedOffset(); + rectF.set(leftX, midY - indicatorSelectedRadius, rightX, midY + indicatorSelectedRadius); + indicatorPaint.setColor(selectedColor); + canvas.drawRoundRect(rectF, indicatorSelectedRadius, indicatorSelectedRadius, indicatorPaint); } private void drawCircleRect(Canvas canvas, float midY) { drawPagerCountCircle(canvas, midY); float indicatorStartX = indicatorStartX(selectedPage); + float ratioRadius = getRatioSelectedRadius(); + float left = indicatorStartX - ratioRadius; + float right = indicatorStartX + ratioRadius; float offset = interpolatedOffset(); - float distance = indicatorSpacing + indicatorRadius * 2; + float distance = indicatorSpacing + getRatioRadius() * 2; float leftX; float rightX; if ((selectedPage + 1) % pagerCount == 0) { distance *= -selectedPage; - leftX = indicatorStartX + Math.max((distance * offset * 2), distance); - rightX = indicatorStartX + Math.min(distance * (offset - 0.5f) * 2.0f, 0); + leftX = left + Math.max((distance * offset * 2), distance); + rightX = right + Math.min(distance * (offset - 0.5f) * 2.0f, 0); } else { - leftX = indicatorStartX + Math.max(distance * (offset - 0.5f) * 2.0f, 0); - rightX = indicatorStartX + Math.min((distance * offset * 2), distance); + leftX = left + Math.max(distance * (offset - 0.5f) * 2.0f, 0); + rightX = right + Math.min((distance * offset * 2), distance); } - if (selectorRect == null) selectorRect = new RectF(); - selectorRect.set(leftX - indicatorRadius, midY - indicatorRadius, rightX + indicatorRadius, midY + indicatorRadius); - canvas.drawRoundRect(selectorRect, indicatorRadius, indicatorRadius, selectedIndicatorPaint); + rectF.set(leftX, midY - indicatorSelectedRadius, rightX, midY + indicatorSelectedRadius); + indicatorPaint.setColor(selectedColor); + canvas.drawRoundRect(rectF, indicatorSelectedRadius, indicatorSelectedRadius, indicatorPaint); } private void drawBezier(Canvas canvas, float midY) { @@ -222,101 +228,207 @@ private void drawBezier(Canvas canvas, float midY) { float nextIndicatorStartX = indicatorStartX((selectedPage + 1) % pagerCount); float leftX = indicatorStartX + (nextIndicatorStartX - indicatorStartX) * accelerateInterpolator.getInterpolation(offset); float rightX = indicatorStartX + (nextIndicatorStartX - indicatorStartX) * interpolatedOffset(); - float minRadius = indicatorRadius * 0.57f; - float leftRadius = indicatorRadius + (minRadius - indicatorRadius) * interpolatedOffset(); - float rightRadius = minRadius + (indicatorRadius - minRadius) * accelerateInterpolator.getInterpolation(offset); - canvas.drawCircle(leftX, midY, leftRadius, selectedIndicatorPaint); - canvas.drawCircle(rightX, midY, rightRadius, selectedIndicatorPaint); + float ratioSelectedRadius = getRatioSelectedRadius(); + float minRadius = indicatorSelectedRadius * 0.57f; + float minRatioRadius = minRadius * indicatorSelectedRatio; + float leftRadius = ratioSelectedRadius + (minRatioRadius - ratioSelectedRadius) * interpolatedOffset(); + float rightRadius = minRatioRadius + (ratioSelectedRadius - minRatioRadius) * accelerateInterpolator.getInterpolation(offset); + float leftTopOrBottomOffset = (indicatorSelectedRadius - minRadius) * interpolatedOffset(); + float rightTopOrBottomOffset = (indicatorSelectedRadius - minRadius) * accelerateInterpolator.getInterpolation(offset); + indicatorPaint.setColor(selectedColor); + rectF.set(leftX + leftRadius, midY - indicatorSelectedRadius + leftTopOrBottomOffset, leftX - leftRadius, midY + indicatorSelectedRadius - leftTopOrBottomOffset); + canvas.drawRoundRect(rectF, leftRadius, leftRadius, indicatorPaint); + rectF.set(rightX + rightRadius, midY - minRadius - rightTopOrBottomOffset, rightX - rightRadius, midY + minRadius + rightTopOrBottomOffset); + canvas.drawRoundRect(rectF, rightRadius, rightRadius, indicatorPaint); path.reset(); path.moveTo(rightX, midY); - path.lineTo(rightX, midY - rightRadius); - path.quadTo(rightX + (leftX - rightX) / 2.0f, midY, leftX, midY - leftRadius); - path.lineTo(leftX, midY + leftRadius); - path.quadTo(rightX + (leftX - rightX) / 2.0f, midY, rightX, midY + rightRadius); + path.lineTo(rightX, midY - minRadius - rightTopOrBottomOffset); + path.quadTo(rightX + (leftX - rightX) / 2.0f, midY, leftX, midY - indicatorSelectedRadius + leftTopOrBottomOffset); + path.lineTo(leftX, midY + indicatorSelectedRadius - leftTopOrBottomOffset); + path.quadTo(rightX + (leftX - rightX) / 2.0f, midY, rightX, midY + minRadius + rightTopOrBottomOffset); path.close(); - canvas.drawPath(path, selectedIndicatorPaint); + canvas.drawPath(path, indicatorPaint); } private void drawDash(Canvas canvas, float midY) { - if (selectorRect == null) selectorRect = new RectF(); - float offset = indicatorSpacing * interpolatedOffset(); + float offset = interpolatedOffset(); + //默认dash的长度,设置ratio控制长度 + float distance = (indicatorSelectedRadius * 2) * indicatorRatio; + float distanceOffset = distance * offset; int nextPage = (selectedPage + 1) % pagerCount; boolean isNextFirst = nextPage == 0; + indicatorPaint.setColor(unColor); for (int i = 0; i < pagerCount; i++) { float startCx = indicatorStartX(i); - if (isNextFirst) startCx += offset; + if (isNextFirst) startCx += distanceOffset; + float ratioIndicatorRadius = getRatioRadius(); + float left = startCx - ratioIndicatorRadius; + float top = midY - indicatorRadius; + float right = startCx + ratioIndicatorRadius; + float bottom = midY + indicatorRadius; if (selectedPage + 1 <= i) { - canvas.drawCircle(startCx + indicatorSpacing, midY, indicatorRadius, indicatorPaint); + rectF.set(left + distance, top, right + distance, bottom); } else { - canvas.drawCircle(startCx, midY, indicatorRadius, indicatorPaint); + rectF.set(left, top, right, bottom); } + canvas.drawRoundRect(rectF, indicatorRadius, indicatorRadius, indicatorPaint); } - if (offset < indicatorSpacing - 1f) { - float leftX = indicatorStartX(selectedPage) - indicatorRadius; - if (isNextFirst) leftX += offset; - float rightX = leftX + indicatorRadius * 2 + indicatorSpacing - offset; - selectorRect.set(leftX, midY - indicatorRadius, rightX, midY + indicatorRadius); - canvas.drawRoundRect(selectorRect, indicatorRadius, indicatorRadius, selectedIndicatorPaint); + indicatorPaint.setColor(selectedColor); + float ratioSelectedRadius = getRatioSelectedRadius(); + if (offset < 0.99f) { + float leftX = indicatorStartX(selectedPage) - ratioSelectedRadius; + if (isNextFirst) leftX += distanceOffset; + float rightX = leftX + ratioSelectedRadius * 2 + distance - distanceOffset; + rectF.set(leftX, midY - indicatorSelectedRadius, rightX, midY + indicatorSelectedRadius); + canvas.drawRoundRect(rectF, indicatorSelectedRadius, indicatorSelectedRadius, indicatorPaint); } - if (offset > 1f) { - float nextRightX = indicatorStartX(nextPage) + indicatorRadius + (isNextFirst ? offset : indicatorSpacing); - float nextLeftX = nextRightX - indicatorRadius * 2 - offset; - selectorRect.set(nextLeftX, midY - indicatorRadius, nextRightX, midY + indicatorRadius); - canvas.drawRoundRect(selectorRect, indicatorRadius, indicatorRadius, selectedIndicatorPaint); + if (offset > 0.1f) { + float nextRightX = indicatorStartX(nextPage) + ratioSelectedRadius + (isNextFirst ? distanceOffset : distance); + float nextLeftX = nextRightX - ratioSelectedRadius * 2 - distanceOffset; + rectF.set(nextLeftX, midY - indicatorSelectedRadius, nextRightX, midY + indicatorSelectedRadius); + canvas.drawRoundRect(rectF, indicatorSelectedRadius, indicatorSelectedRadius, indicatorPaint); } } private void drawBigCircle(Canvas canvas, float midY) { drawPagerCountCircle(canvas, midY); float offset = interpolatedOffset(); - int nextPage = (selectedPage + 1) % pagerCount; float indicatorStartX = indicatorStartX(selectedPage); - float nextIndicatorStartX = indicatorStartX(nextPage); - float maxRadius = indicatorRadius * 1.5f; - float leftRadius = maxRadius - ((maxRadius - indicatorRadius) * offset); - float rightRadius = indicatorRadius + ((maxRadius - indicatorRadius) * offset); - if (offset < 0.9) { - canvas.drawCircle(indicatorStartX, midY, leftRadius, selectedIndicatorPaint); + float nextIndicatorStartX = indicatorStartX((selectedPage + 1) % pagerCount); + float ratioRadius = getRatioRadius(); + float maxRadius = indicatorRadius == indicatorSelectedRadius ? indicatorSelectedRadius * 1.5f : indicatorSelectedRadius; + float maxRatioRadius = maxRadius * indicatorSelectedRatio; + float leftRadius = maxRatioRadius - ((maxRatioRadius - ratioRadius) * offset); + float rightRadius = ratioRadius + ((maxRatioRadius - ratioRadius) * offset); + float topOrBottomOffset = (maxRadius - indicatorRadius) * offset; + indicatorPaint.setColor(selectedColor); + if (offset < 0.99f) { + float top = midY - maxRadius + topOrBottomOffset; + float left = indicatorStartX - leftRadius; + float right = indicatorStartX + leftRadius; + float bottom = midY + maxRadius - topOrBottomOffset; + rectF.set(left, top, right, bottom); + canvas.drawRoundRect(rectF, leftRadius, leftRadius, indicatorPaint); } if (offset > 0.1f) { - canvas.drawCircle(nextIndicatorStartX, midY, rightRadius, selectedIndicatorPaint); + float top = midY - indicatorRadius - topOrBottomOffset; + float left = nextIndicatorStartX - rightRadius; + float right = nextIndicatorStartX + rightRadius; + float bottom = midY + indicatorRadius + topOrBottomOffset; + rectF.set(left, top, right, bottom); + canvas.drawRoundRect(rectF, rightRadius, rightRadius, indicatorPaint); } } private void drawPagerCountCircle(Canvas canvas, float midY) { + indicatorPaint.setColor(unColor); for (int i = 0; i < pagerCount; i++) { float startCx = indicatorStartX(i); - canvas.drawCircle(startCx, midY, indicatorRadius, indicatorPaint); + float ratioIndicatorRadius = getRatioRadius(); + float left = startCx - ratioIndicatorRadius; + float top = midY - indicatorRadius; + float right = startCx + ratioIndicatorRadius; + float bottom = midY + indicatorRadius; + rectF.set(left, top, right, bottom); + canvas.drawRoundRect(rectF, indicatorRadius, indicatorRadius, indicatorPaint); } } private float indicatorStartX(int index) { - float centerSpacing = indicatorRadius * 2.0f + indicatorSpacing; - return indicatorRadius + getPaddingLeft() + centerSpacing * index; + float ratioIndicatorRadius = getRatioRadius(); + float centerSpacing = ratioIndicatorRadius * 2.0f + indicatorSpacing; + return ratioIndicatorRadius + getPaddingLeft() + centerSpacing * index; + } + + private float getRatioRadius() { + return indicatorRadius * indicatorRatio; } + private float getRatioSelectedRadius() { return indicatorSelectedRadius * indicatorSelectedRatio; } + private float interpolatedOffset() { return interpolator.getInterpolation(offset); } - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - selectedPage = position; - offset = positionOffset; - invalidate(); + private int dip2px(float dp) { return (int) (dp * getContext().getResources().getDisplayMetrics().density); } + + /*--------------- 下面是暴露的方法 ---------------*/ + + /** + * 设置indicator的圆角,同时会改变选中时的圆角,default 3.5dp + * + * @param indicatorRadius 单位dp + */ + public IndicatorView setIndicatorRadius(float indicatorRadius) { + int indicatorRadiusDp = dip2px(indicatorRadius); + if (this.indicatorRadius == this.indicatorSelectedRadius) { + this.indicatorSelectedRadius = indicatorRadiusDp; + } + this.indicatorRadius = indicatorRadiusDp; + return this; } - @Override - public void onPageSelected(int position) { + /** + * 设置indicator比例,拉伸圆为矩形,控制该比例,default 1.0 + * {@link IndicatorView#getRatioRadius()} + * + * @param indicatorRatio indicatorRadius * indicatorRatio + */ + public IndicatorView setIndicatorRatio(float indicatorRatio) { + if (this.indicatorRatio == this.indicatorSelectedRatio) { + this.indicatorSelectedRatio = indicatorRatio; + } + this.indicatorRatio = indicatorRatio; + return this; + } + /** + * 设置选中的圆角,没有设置,默认和indicatorRadius值一致 + * + * @param indicatorSelectedRadius 单位dp + */ + public IndicatorView setIndicatorSelectedRadius(float indicatorSelectedRadius) { + this.indicatorSelectedRadius = dip2px(indicatorSelectedRadius); + return this; } - @Override - public void onPageScrollStateChanged(int state) { + /** + * 设置选中圆比例,拉伸圆为矩形,控制该比例,默认比例和indicatorRatio一致 + * + * @param indicatorSelectedRatio indicatorSelectedRadius * indicatorSelectedRatio + */ + public IndicatorView setIndicatorSelectedRatio(float indicatorSelectedRatio) { + this.indicatorSelectedRatio = indicatorSelectedRatio; + return this; + } + + /** + * 设置点与点之间的距离,default dp10 + * + * @param indicatorSpacing 单位dp + */ + public IndicatorView setIndicatorSpacing(float indicatorSpacing) { + this.indicatorSpacing = dip2px(indicatorSpacing); + return this; + } + + public IndicatorView setIndicatorStyle(@IndicatorStyle int indicatorStyle) { + this.indicatorStyle = indicatorStyle; + return this; + } + + public IndicatorView setIndicatorColor(@ColorInt int indicatorColor) { + this.unColor = indicatorColor; + return this; + } + public IndicatorView setIndicatorSelectorColor(@ColorInt int indicatorSelectorColor) { + this.selectedColor = indicatorSelectorColor; + return this; } - private int dip2px(float dp) { - return (int) (dp * getContext().getResources().getDisplayMetrics().density); + public IndicatorView setParams(RelativeLayout.LayoutParams params) { + this.params = params; + return this; } }