The small red dot indicator is often used in our development. Previously, we used to perform related calculations in the scroll monitor of ViewPager. It was very complicated to write a set every time. Today I have collected a package class for the small red dot indicator, and everyone can use it.
The first is a custom control for the indicator
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); // 四舍五入取整
}
}
Then we will use this indicator in our layout. The example layout is as follows
<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>
We can see that the PagerIndicator should be stacked on top of the ViewPager in the layout.
Then we need to get the PagerIndicator control in Activity and call
pageIndicator.setCount(4,20);
Set the number and spacing of small red dots.
Pass in the corresponding value in ViewPager's 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) {
}
});
In this way, the linkage between the little red dot and ViewPager is realized.