千家信息网

Android如何自定义圆点指示器

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,这篇文章主要讲解了"Android如何自定义圆点指示器",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Android如何自定义圆点指示器"吧!先上效果图
千家信息网最后更新 2025年01月21日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()方法

@Override    protected 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()方法

@Override    protected 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;    }

下面是MainActivity的布局代码,很简单

           

下面是MainActivity的代码

public class MainActivity extends AppCompatActivity {     View layout1,layout2,layout3;    ViewPager viewPager;    Indicator indicator;     List viewList;     @Override    protected 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() {            @Override            public int getCount() {                return viewList.size();            }             @Override            public void destroyItem(ViewGroup container, int position, Object object) {                container.removeView(viewList.get(position));            }             @Override            public Object instantiateItem(ViewGroup container, int position) {                container.addView(viewList.get(position));                 return position;            }             @Override            public 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{          @Override        public void onPageSelected(int position) {             indicator.setCurrentIndex(position);        }         @Override        public void onPageScrollStateChanged(int state) {         }         @Override        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {         }    }

ViewPager里添加了三个空页面 然后设置指示器的圆点个数,最后在ViewPager的OnPageChangeListener中设置当前的 页面的圆点。

感谢各位的阅读,以上就是"Android如何自定义圆点指示器"的内容了,经过本文的学习后,相信大家对Android如何自定义圆点指示器这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0