import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import com.hcb.fixorder.R;
import com.orhanobut.logger.Logger;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
/**
* viewpager 底部指示器
*
* @author 陈聪 2020-05-11 10:59
*/
public class CuteIndicator extends LinearLayout {
/** 显示个数 */
private int itemCount = 0;
/** 选中宽度 */
private float selectedWidth = 0f;
/** 点大小 */
private float dia = 0f;
/** 间隔大小 */
private float space = 0f;
/** 阴影大小 */
private float shadowRadius = 0f;
/** 位置 */
private RectF rectf = new RectF();
/** 画笔 */
private Paint paint;
/** 上个点偏移量 */
private float lastPositionOffset = 0f;
/** 选中点偏移量 */
private int firstVisiblePosition = 0;
/** 点颜色 */
private int indicatorColor = 0xffffffff;
/** 选中点颜色 */
private int indicatorSelectColor = 0xffffffff;
/** 阴影颜色 */
private int shadowColor = 0x88000000;
/** 是否使用动画 */
private boolean isAnimation = true;
/** 是否使用阴影 */
private boolean isShadow = true;
public CuteIndicator(Context context) {
super(context);
init(null, 0);
}
public CuteIndicator(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public CuteIndicator(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
//默认值
selectedWidth = dp2px(20f);
dia = dp2px(10f);
space = dp2px(5f);
shadowRadius = dp2px(2f);
setWillNotDraw(false);
// Load attributes
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CuteIndicator, defStyle, 0);
indicatorColor = a.getColor(R.styleable.CuteIndicator_IndicatorColor, indicatorColor);
indicatorSelectColor = a.getColor(R.styleable.CuteIndicator_IndicatorSelectColor, indicatorSelectColor);
shadowColor = a.getColor(R.styleable.CuteIndicator_IndicatorShadowColor, shadowColor);
selectedWidth = a.getDimension(R.styleable.CuteIndicator_IndicatorSelectedWidthDimension, selectedWidth);
dia = a.getDimension(R.styleable.CuteIndicator_IndicatorDiaDimension, dia);
space = a.getDimension(R.styleable.CuteIndicator_IndicatorSpaceDimension, space);
shadowRadius = a.getDimension(R.styleable.CuteIndicator_IndicatorShadowRadiusDimension, shadowRadius);
isAnimation = a.getBoolean(R.styleable.CuteIndicator_IndicatorIsAnimation, isAnimation);
isShadow = a.getBoolean(R.styleable.CuteIndicator_IndicatorIsShadow, isShadow);
a.recycle();
if (isShadow) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(indicatorColor);
paint.setStyle(Paint.Style.FILL);
if (isShadow) {
paint.setShadowLayer(shadowRadius, shadowRadius / 2, shadowRadius / 2, shadowColor);
}
}
public void setupWithViewPager(final ViewPager viewPager) {
if (viewPager.getAdapter() == null) {
Logger.e("viewPager adapter not be null");
return;
}
setWH(viewPager);
viewPager.getAdapter().registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
setWH(viewPager);
}
});
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
if (isAnimation) {
firstVisiblePosition = position;
lastPositionOffset = positionOffset;
invalidate();
}
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (!isAnimation) {
firstVisiblePosition = position;
invalidate();
}
}
});
}
private void setWH(ViewPager viewPager) {
itemCount = viewPager.getAdapter().getCount();
if (isShadow) {
getLayoutParams().width = (int) ((itemCount - 1) * (space + dia) + selectedWidth + shadowRadius);
getLayoutParams().height = (int) (dia + shadowRadius);
} else {
getLayoutParams().width = (int) ((itemCount - 1) * (space + dia) + selectedWidth);
getLayoutParams().height = (int) dia;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || itemCount == 0) {
return;
}
for (int i = 0; i < itemCount; i++) {
float left;
float right;
paint.setColor(indicatorColor);
if (i < firstVisiblePosition) {
left = i * (dia + space);
right = left + dia;
} else if (i == firstVisiblePosition) {
left = i * (dia + space);
right = left + dia + (selectedWidth - dia) * (1 - lastPositionOffset);
} else if (i == firstVisiblePosition + 1) {
left = (i - 1) * (space + dia) + dia + (selectedWidth - dia) * (1 - lastPositionOffset) + space;
right = i * (space + dia) + selectedWidth;
} else {
left = (i - 1) * (dia + space) + (selectedWidth + space);
right = (i - 1) * (dia + space) + (selectedWidth + space) + dia;
}
float top = 0f;
float bottom = dia;
rectf.left = left;
rectf.top = top;
rectf.right = right;
rectf.bottom = bottom;
if (i == firstVisiblePosition) {
paint.setColor(indicatorSelectColor);
}
canvas.drawRoundRect(rectf, dia / 2, dia / 2, paint);
}
}
private float dp2px(float dpValue) {
return dpValue * getContext().getResources().getDisplayMetrics().density;
}
}
<declare-styleable name="CuteIndicator">
<attr name="IndicatorColor" format="color"/>
<attr name="IndicatorSelectColor" format="color"/>
<attr name="IndicatorShadowColor" format="color"/>
<attr name="IndicatorSelectedWidthDimension" format="dimension"/>
<attr name="IndicatorDiaDimension" format="dimension"/>
<attr name="IndicatorSpaceDimension" format="dimension"/>
<attr name="IndicatorShadowRadiusDimension" format="dimension"/>
<attr name="IndicatorIsAnimation" format="boolean"/>
<attr name="IndicatorIsShadow" format="boolean"/>
</declare-styleable>
网友评论