ViewPager中小点的实现+自定义View中设置属性

在自定义控件里设置属性的大纲
* 0.Values创建一个xml资源文件
* 1.xml资源文件,定义表头和属性
* 2.在构造方法里进行属性的关联
* 3.同步gradle文件,否则在xml布局文件中依然无法引用
* 4.xml布局文件里进行使用
<resources>
    <!--指定这些属性都是谁的,注意这里添加完属性要在自定义View类构造方法中应用-->
    <!--注意:写完这个属性之后,布局xml文件要想应用的话,必须同步gradle文件-->
    <declare-styleable name="Indicator">
        <!--定义控件显示圆的数量 参数format是类型-->
        <attr name="setNumber" format="integer"></attr>
        <!--定义控件显示圆的半径 参数format是类型-->
        <attr name="setRadius" format="integer"></attr>
        <!--定义空心圆的颜色 参数format是类型,reference表示什么都能装-->
        <attr name="setForeColor" format="color"></attr>
        <!--定义控件显示圆的后颜色 参数format是类型,reference表示什么都能装-->
        <attr name="setbgColor" format="color"></attr>
    </declare-styleable>
</resources>

在MainActivity布局文件中使用时(要先同步gradle才能使用):
<com.zhiyuan3g.indicator.Indicator
    android:id="@+id/indicator"
    app:setNumber="4"
    app:setRadius="10"
    app:setForeColor="#FF0800FF"
    app:setbgColor="#FFFF0000"
    android:layout_width="160dp"
    android:layout_height="60dp"
    android:layout_alignBottom="@+id/viewPager"
    android:layout_centerHorizontal="true"/>


public class Indicator extends View {
    //前面的圆
    private Paint forePaint;
    //后面的圆
    private Paint bgPaint;
    //规定圆的数量,默认是4,如果有xml指定的数量,使用指定的
    private int number;
    //圆的半径,规定默认值为10,如果有xml指定的数量,使用指定的
    private int radius;
    //定义圆(空心圆)的背景颜色,默认红色,如果有xml指定的数量,使用指定的
    private int bgColor;
    //定义圆(实心圆)的颜色,默认蓝色,如果有xml指定的数量,使用指定的
    private int foreColor;
    //移动的偏移量
    private float offset;

    //在代码中添加我们自定义的View,所调用的构造方法
    public Indicator(Context context) {
        super(context);
        initPaint();
    }

    //XML文件中添加我们自定义的控件时,所调用的方法,多了一个参数
    public Indicator(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
        //引用atts文件下,给自定义控件设置属性,得到typdeArray对象,
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Indicator);
        //使用TypedArray对象,把在自定义控件属性和XML文件里设置的属性进行关联,才算完成
        //注意:你在xml文件中设置的类型属性,获取时,也要是对应的类型
        number = typedArray.getInteger(R.styleable.Indicator_setNumber, number);
        radius = typedArray.getInteger(R.styleable.Indicator_setRadius, radius);
        foreColor = typedArray.getInteger(R.styleable.Indicator_setForeColor, foreColor);
        bgColor = typedArray.getInteger(R.styleable.Indicator_setbgColor, bgColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        initPaint();
    }

    //参数就是画板,可以直接使用
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initPaint();
        for (int i = 0; i < number; i++) {
            //画多个空心圆,为了使圆不要挤在一起,所以对x轴坐标进行动态的修改
            canvas.drawCircle(60 + radius * 3 * i, 60, 10, bgPaint);
        }
        //画前面的圆
        canvas.drawCircle(60 + offset, 60, 10, forePaint);
    }

    private void initPaint() {
        //shift+F6可以更改所有对象名
        //ctrl+alt+F可以抽取成员变量
        //创建画笔的对象
        forePaint = new Paint();
        //设置抗锯齿
        forePaint.setAntiAlias(true);
        //设置颜色
        forePaint.setColor(foreColor);
        //设置样式
        forePaint.setStyle(Paint.Style.FILL);
        //设置画笔的宽度
        forePaint.setStrokeWidth(2);

        bgPaint = new Paint();
        bgPaint.setAntiAlias(true);
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setColor(bgColor);
        bgPaint.setStrokeWidth(2);
    }

    public void setoffset(int position, float positionOffset) {
        position %= number;
        //因为从一个圆到另一个圆经过3个半径,两个圆各两个半径,中间的间距1个半径
        if (!(position == number-1)) {
            offset = position * 3 * radius + positionOffset * 3 * radius;
        }
        //关键一点,重新绘制自定义View的方法,十分有用
        invalidate();
    }
}


public class MainActivity extends AppCompatActivity {
//创建一个集合用来装ViewPager加载的图片控件
private List<View> views = new ArrayList<>();
private Indicator indicator;
private int[] picture = {R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //初始化ViewPageritem数据
    initData();
    //初始化控件
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
    //设置ViewPager适配器
    viewPager.setAdapter(new MyPagerAdapter());
    //设置ViewPager的监听器
    viewPager.setOnPageChangeListener(new MyPagerListener());
    indicator = (Indicator) findViewById(R.id.indicator);
}

private void initData() {
    for (int i = 0; i < 4; i++) {
        View inflate = getLayoutInflater().inflate(R.layout.pager_item, null);
        ImageView imageView = (ImageView) inflate.findViewById(R.id.imgShow);
        imageView.setImageResource(picture[i]);
        views.add(inflate);
    }
}

//创建Viewpager的适配器,重写四个方法
private class MyPagerAdapter extends PagerAdapter {
    //设置ViewPageritem数量
    @Override
    public int getCount() {
        return 10000;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        position %=views.size();
        container.removeView(views.get(position));
    }

    //类似于ListViewAdapter里的GetView,参数1:ViewPager的化身, 参数2:item的位置
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        position %=views.size();
        //从集合里拿对应位置的图片
        View view = views.get(position);
        //ImageView对象添加到ViewPager        container.addView(view);
        return view;
    }
}

//创建ViewPager的监听事件
private class MyPagerListener implements ViewPager.OnPageChangeListener{
    //ViewPager滑动时回调  参数1:item的位置 参数2:偏移的百分比 参数3:偏移量
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        indicator.setoffset(position,positionOffset);
    }

    //ViewPager选中时回调
    @Override
    public void onPageSelected(int position) {

    }

    //ViewPager滑动状态改变时回调
    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值