美文网首页
Android ViewPager Indicator 一个图片

Android ViewPager Indicator 一个图片

作者: The_Ashes | 来源:发表于2018-12-02 20:22 被阅读0次

一、效果

切换方式:

目前有四种切换方式
1、直接切换

直接切换.gif
2、渐变
渐变.gif
3、滑动
滑动.gif
4、滚动
滚动.gif

四种形状:

圆形、正方形、菱形、三角形(若选择菱形滚动模式因动效半径问题,默认效果为滑动)

二、用法

1、在项目中app的build.gralde中添加

implementation 'com.chz.view:guide:1.2'

2、在需要用到指示器的父布局文件下
注意
合理设置指示器数量、尺寸、间距

    <com.chz.guide.view.GuideView
        android:id="@+id/circle_change_guide"
        android:layout_width="wrap_content"//参数被屏蔽,失效
        android:layout_height="wrap_content"//参数被屏蔽,失效
        app:changeMode="change"//切换模式,不声明默认为'改变'
        app:distanceSize="50dp"//指示器之间的距离(大于等于0)
        app:focusColor="#FF0000"//选中指示器颜色
        app:guideShape="circle"//指示器形状,不声明默认为'圆形'
        app:indexCount="4"//指示器数量(大于等于0)
        app:indexSize="50dp"//指示器尺寸(大于0)
        app:normalColor="#0000FF"//非选中指示器颜色
    />

3、在你的Activity或者Fragment中

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circle_alpha);
        //找到Viewpager控件
        viewPager = findViewById(R.id.circle_alpha_vp);
        //找到指示器控件
        guideView = findViewById(R.id.circle_alpha_guide);
        //Viewpager适配器初始化
        PagerAdapter adapter = new GuideAdapter(this);
        //设置适配器
        viewPager.setAdapter(adapter);
        //调用GuideView的addOnPageChangeListener方法,将Viewpager作为参数传进去
        guideView.addOnPageChangeListener(viewPager);
        //主动设置当前ViewPager position
        guideView.updatePosition(position);
    }

三、源码解读

1、架构

两个重点:形状、切换效果

代码架构.png

2、自定义的GuideView

1.自定义View xml资源文件
形状和切换模式使用枚举来表示,并且为了避免魔鬼数字,均为两位数

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="indexSize" format="dimension" />
    <attr name="distanceSize" format="dimension" />
    <attr name="indexCount" format="integer" />
    <attr name="focusColor" format="color" />
    <attr name="normalColor" format="color" />
    <attr name="guideShape">
        <enum name="circle" value="11" />
        <enum name="square" value="22" />
        <enum name="diamond" value="33" />
        <enum name="triangle" value="44" />
    </attr>
    <attr name="changeMode">
        <enum name="change" value="11" />
        <enum name="alpha" value="22" />
        <enum name="slide" value="33" />
        <enum name="scroll" value="44" />
    </attr>
    <declare-styleable name="GuideView">
        <attr name="indexSize" />
        <attr name="distanceSize" />
        <attr name="indexCount" />
        <attr name="focusColor" />
        <attr name="normalColor" />
        <attr name="guideShape" />
        <attr name="changeMode" />
    </declare-styleable>
</resources>

2.GuideView类
GuideView仅作为一个承载容器,负责形状基础参数的初始化和边界合法性判断

 public GuideView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
       ······
        initShape();
        //指示器参数初始化
        shape.baseInit(changeMode, indexShape,normalColor, focusColor, indexSize,
                distanceSize, indexCount, scrollCount);
    }
//判断指示器控件是否超出父容器边界
    private void checkViewSize() {
         ······
    }

在GuideView中初始化控件尺寸
宽度=指示器宽度*指示器数量+指示器间距*指示器间距数量
高度分两种情况
滚动模式下:
正方形的最大高度为对角线长度,三角形最大高度为边长,剩余两种形状高度与非滚动模式下相同。
非滚动模式下:
圆形、正方形、菱形的高都为指示器宽度,而形状为三角形,控件的高则为当前正三角形的高。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        viewWidth = (int) (indexCount * (indexSize + distanceSize) - distanceSize);
        viewHeight = (int) indexSize;
        switch (indexShape) {
            case SHAPE_CIRCLE:
                break;
            case SHAPE_SQUARE:
                if (changeMode == MODE_SCROLL) {
                    viewHeight = (int) (indexSize / Math.cos(45 *PI));
                }
                break;
            case SHAPE_DIAMOND:
                break;
            case SHAPE_TRIANGLE:
                if (changeMode != MODE_SCROLL) {
                    viewHeight = (int) (indexSize / 2 * Math.tan(60 * PI));
                }
                break;
            default:
                break;
        }
        setMeasuredDimension(viewWidth, viewHeight);
    }

3.GuideShape类
GuideShape是一个抽象类,实现了ViewPager的滑动监听方法,负责所有形状的公共参数初始化,形状切换状态也实现的ViewPager滑动监听方法中实现。

public abstract class GuideShape implements ViewPager.OnPageChangeListener {
    ······
    public void baseInit(int mode, int shape, int normalColor, int focusColor
            , float indexSize, float distanceSize, int indexCount, int scrollCount) {
        ······
        normalPaint = new Paint();
        focusPaint = new Paint();
        normalPaint.setAntiAlias(true);
        focusPaint.setAntiAlias(true);
        normalPaint.setColor(mNormalColor);
        focusPaint.setColor(mFocusColor);
        if (mMode == GuideView.MODE_ALPHA) {
            focusPaintNormal = new Paint();
            focusPaintNormal.setAntiAlias(true);
            focusPaintNormal.setColor(mFocusColor);
            focusPaintNormal.setAlpha(0);
        }
        initPaintTools();
    }

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        switch (mMode) {
            case GuideView.MODE_CHANGE:
                ······    
                break;
            case GuideView.MODE_ALPHA:
                ······ 
                break;
            case GuideView.MODE_SLIDE:
                ······ 
                break;
            case GuideView.MODE_SCROLL:
                ······ 
                break;
        }
    }

    public void onPageSelected(int position) {
    }

    public void onPageScrollStateChanged(int state) {
        ······ 
    }

3.Circle、Triangle、Square、Diamond类
对应形状的绘制实现、刷新等。

四、版本更新

Version 1.2

1、新增“滚动”模式
2、优化响应模式

Version 1.1

1、优化重绘机制
2、自适应父布局

Version 1.0

Release notes 初始化提交

四、其他

github
望诸君多多指教!

相关文章

网友评论

      本文标题:Android ViewPager Indicator 一个图片

      本文链接:https://www.haomeiwen.com/subject/hkjscqtx.html