欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义圆点指示器

程序员文章站 2022-03-07 12:46:24
本文实例为大家分享了android自定义圆点指示器的具体代码,供大家参考,具体内容如下先上效果图大概思路就是自定义view 从左至右绘制圆点 然后在viewpager的onpagechangelist...

本文实例为大家分享了android自定义圆点指示器的具体代码,供大家参考,具体内容如下

先上效果图

Android自定义圆点指示器

大概思路就是自定义view 从左至右绘制圆点 然后在viewpager的onpagechangelistener中设置当前页面的圆点

下面是代码

先定义属性

<resources>
    <attr name="selectedcolor" format="color"/>
    <attr name="unselectedcolor" format="color"/>
    <declare-styleable name="indicator">
        <attr name="selectedcolor"/>
        <attr name="unselectedcolor"/>
    </declare-styleable>
</resources>

接下来是自定义的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的布局代码,很简单

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.lzh123.learnviewpager.mainactivity">
 
    <android.support.v4.view.viewpager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
 
    <com.example.lzh123.learnviewpager.indicator
        app:selectedcolor="#ffffff"
        app:unselectedcolor="#c7c7c7"
        android:id="@+id/indicator"
        android:layout_centerinparent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 
</relativelayout>

下面是mainactivity的代码

public class mainactivity extends appcompatactivity {
 
    view layout1,layout2,layout3;
    viewpager viewpager;
    indicator indicator;
 
    list<view> 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 指示器