Android自定义圆点指示器

本文实例为大家分享了Android自定义圆点指示器的具体代码,供大家参考,具体内容如下
先上效果图
Android自定义圆点指示器
文章图片

大概思路就是自定义View 从左至右绘制圆点 然后在ViewPager的OnPageChangeListener中设置当前页面的圆点
下面是代码
先定义属性


接下来是自定义的View
public class Indicator extends View{ private static final int DEFAULT_TOTAL_INDEX = 5; private static final int DEFAULT_CURRENT_INDEX = 0; private static final int DEFAULT_CIRCLE_DISTANCE = 40; private static final int DEFAULT_CIRCLE_RADIUS = 8; private static final int DEFAULT_CIRCLE_SELECTED_RADIUS = 11; private int selectedColor; private int unselectedColor; private int currentIndex; private int totalIndex; private Paint paint; private int startX; private int startSelectedY; private int startY; private int centreX; public Indicator(Context context) {this(context,null); } public Indicator(Context context, AttributeSet attrs) {this(context, attrs,0); } public Indicator(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr); TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,R.styleable.Indicator,defStyleAttr,0); selectedColor = typedArray.getColor(R.styleable.Indicator_selectedColor, Color.LTGRAY); unselectedColor = typedArray.getColor(R.styleable.Indicator_unselectedColor,Color.WHITE); typedArray.recycle(); totalIndex = DEFAULT_TOTAL_INDEX; currentIndex = DEFAULT_CURRENT_INDEX; paint = new Paint(); }

从TypedArray中获取自定义的属性,totalIndex是总的圆点个数,currentIndex是当前页面的圆点
接下来是重写的OnDraw()方法
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas); centreX = getWidth() / 2; startSelectedY = getHeight() / 2 - DEFAULT_CIRCLE_SELECTED_RADIUS; startY = getHeight() / 2 - DEFAULT_CIRCLE_RADIUS; if (totalIndex % 2 == 0){startX = centreX - (int)(1.0 * (totalIndex - 1)/2 * DEFAULT_CIRCLE_DISTANCE); }else{startX = centreX - totalIndex / 2 * DEFAULT_CIRCLE_DISTANCE; }paint.setAntiAlias(true); paint.setColor(unselectedColor); int tempX = startX; for(int i = 0 ; i < totalIndex ; i++ ){RectF rectF = new RectF(tempX - DEFAULT_CIRCLE_RADIUS,startY,tempX + DEFAULT_CIRCLE_RADIUS,startY + 2 * DEFAULT_CIRCLE_RADIUS); if (i == currentIndex) {paint.setColor(selectedColor); rectF = new RectF(tempX - DEFAULT_CIRCLE_SELECTED_RADIUS,startSelectedY,tempX + DEFAULT_CIRCLE_SELECTED_RADIUS,startSelectedY + 2 * DEFAULT_CIRCLE_SELECTED_RADIUS); }canvas.drawOval(rectF,paint); if (paint.getColor() == selectedColor)paint.setColor(unselectedColor); tempX += DEFAULT_CIRCLE_DISTANCE; }}

因为当前页面的圆点和未选中页面的圆点要设置不同的大小 所以分别设置每个圆点的坐标 然后用for循环绘制圆点
这里有一点要注意 new RectF() 的四个参数分别是圆点外面的矩形的左上角的X,Y和右下角的X,Y
接下来是设置当前页面的圆点的方法
public void setCurrentIndex(int currentIndex){//if (currentIndex < 0)//currentIndex += totalIndex ; //if (currentIndex > totalIndex - 1)//currentIndex %= totalIndex; this.currentIndex = currentIndex; invalidate(); }

注释里的代码是当页面可以循环的时候设置的
接下来是设置总的圆点个数的方法
public void setTotalIndex(int totalIndex){int oldTotalIndex = this.totalIndex; if (totalIndex < 1)return; if (totalIndex < oldTotalIndex){if (currentIndex == totalIndex )currentIndex = totalIndex - 1; }this.totalIndex = totalIndex; invalidate(); }

当删除圆点的时候 如果currentIndex是最后一个 让currentIndex向前移动
接下来是重写的OnMeasure()方法
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec)); } private int measureHeight(int measureSpec){int result; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); int desired = DEFAULT_CIRCLE_SELECTED_RADIUS * 2 + getPaddingBottom() + getPaddingTop(); if(specMode == MeasureSpec.EXACTLY) {result = Math.max(desired,specSize); }else{if(specMode == MeasureSpec.AT_MOST){result = Math.min(desired,specSize); }else result = desired; }return result; } private int measureWidth(int measureSpec){int result; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); int desired = (totalIndex - 1) * DEFAULT_CIRCLE_DISTANCE + DEFAULT_CIRCLE_SELECTED_RADIUS * 2 + getPaddingLeft() + getPaddingRight(); if(specMode == MeasureSpec.EXACTLY) {result = Math.max(desired,specSize); }else{if(specMode == MeasureSpec.AT_MOST){result = Math.min(desired,specSize); }else result = desired; }return result; }

【Android自定义圆点指示器】下面是MainActivity的布局代码,很简单

下面是MainActivity的代码
public class MainActivity extends AppCompatActivity { View layout1,layout2,layout3; ViewPager viewPager; Indicator indicator; List viewList; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager); LayoutInflater inflater = getLayoutInflater(); layout1 = inflater.inflate(R.layout.layout1,null); layout2 = inflater.inflate(R.layout.layout2,null); layout3 = inflater.inflate(R.layout.layout3,null); viewList = new ArrayList<>(); viewList.add(layout1); viewList.add(layout2); viewList.add(layout3); indicator = (Indicator) findViewById(R.id.indicator); indicator.setTotalIndex(viewList.size()); PagerAdapter pagerAdapter = new PagerAdapter() {@Overridepublic int getCount() {return viewList.size(); } @Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView(viewList.get(position)); } @Overridepublic Object instantiateItem(ViewGroup container, int position) {container.addView(viewList.get(position)); return position; } @Overridepublic boolean isViewFromObject(View view, Object object) {return view == viewList.get(Integer.parseInt(object.toString())); }}; viewPager.setAdapter(pagerAdapter); viewPager.setOnPageChangeListener(new PageChangeListener()); } public class PageChangeListener implements ViewPager.OnPageChangeListener{ @Overridepublic void onPageSelected(int position) { indicator.setCurrentIndex(position); } @Overridepublic void onPageScrollStateChanged(int state) { } @Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }}

ViewPager里添加了三个空页面 然后设置指示器的圆点个数,最后在ViewPager的OnPageChangeListener中设置当前的 页面的圆点。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读