小红点指示器在我们的开发中时常会用到,之前的时候都是我们在ViewPager的滚动监听中进行相关的计算,每次都要写一套很复杂。今天收集来了一个小红点指示器的封装类,大家可以拿来使用。
首先是一个指示器的自定义控件
public class PagerIndicator extends LinearLayout {
private static final String TAG = "PagerIndicator";
private Context mContext; // 声明一个上下文对象
private int mCount = 5; // 指示器的个数
private int mPad; // 两个圆点之间的间隔
private int mSeq = 0; // 当前指示器的序号
private float mRatio = 0.0f; // 已经移动的距离百分比
private Paint mPaint; // 声明一个画笔对象
private Bitmap mBackImage; // 背景位图,通常是灰色圆点
private Bitmap mForeImage; // 前景位图,通常是高亮的红色圆点
public PagerIndicator(Context context) {
this(context, null);
}
public PagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
private void init() {
// 创建一个新的画笔
mPaint = new Paint();
mPad = dip2px(mContext, 15);
// 从资源图片icon_point_n.png中得到背景位图对象
mBackImage = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_point_n);
// 从资源图片icon_point_c.png中得到前景位图对象
mForeImage = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_point_c);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
int left = (getMeasuredWidth() - mCount * mPad) / 2;
// 先绘制作为背景的几个灰色圆点
for (int i = 0; i < mCount; i++) {
canvas.drawBitmap(mBackImage, left + i * mPad, 0, mPaint);
}
// 再绘制作为前景的高亮红点,该红点随着翻页滑动而左右滚动
canvas.drawBitmap(mForeImage, left + (mSeq + mRatio) * mPad, 0, mPaint);
}
// 设置指示器的个数,以及指示器之间的距离
public void setCount(int count, int pad) {
mCount = count;
mPad = dip2px(mContext, pad);
invalidate(); // 立刻刷新视图
}
// 设置指示器当前移动到的位置,及其位移比率
public void setCurrent(int seq, float ratio) {
mSeq = seq;
mRatio = ratio;
invalidate(); // 立刻刷新视图
}
// 根据手机的分辨率从 dp 的单位 转成为 px(像素)
public static int dip2px(Context context, float dpValue) {
// 获取当前手机的像素密度
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f); // 四舍五入取整
}
}
接着我们的布局中要用上这个指示器,示例布局如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.hao.tooldesign.PagerIndicator
android:id="@+id/pageIndicator"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginBottom="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_title"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabIndicatorColor="#FF0000"
app:tabIndicatorHeight="2dp"
app:tabSelectedTextColor="#FF0000"
app:tabTextColor="#666666"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"/>
</LinearLayout>
我们可以看到,布局中要把PagerIndicator叠放在ViewPager上方。
接着我们需要在Activity中获取到PagerIndicator控件,并调用
pageIndicator.setCount(4,20);
设置小红点的数量和间距。
在ViewPager的OnPageChangeListener中传入对应的值即可
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
pageIndicator.setCurrent(position,positionOffset);
}
@Override
public void onPageSelected(int position) {
pageIndicator.setCurrent(position,0);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
这样就实现了小红点和ViewPager的联动。