以前在项目中使用线性布局实现该效果,感觉操作很繁琐而且很不利于复用,于是封装了一个简单的指示器类。 这是一个非常简单的ViewPager页码指示器,实现方式只有一个继承View的自定义View。
IndicatorView主要使用场景如下:
- 引导页页码指示
- 轮播图页码指示
IndicatorView的优点:
- 很轻量级:继承自View
- 样式定制性高:通过StateListDrawable(即XML)配置选择图形,支持使用图片的默认宽高
- 自定义动画:通过实现IndicatorTransformer接口实现切换动画,内置平移动画TranslationIndicatorTransformer
使用Android Studio
在build.gradle中添加如下代码:
dependencies {
compile 'cn.junhua.android.view:indicatorviewlibrary:1.2.1'
}
出现依赖冲突可以剔除内部依赖的v4包:
implementation ('cn.junhua.android.view:indicatorviewlibrary:1.2.0'){
exclude module: 'support-v4'
}
<cn.junhua.android.view.IndicatorView android:id="@+id/indicator_view" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
这是最简单的使用方法,默认样式如下图:
IndicatorView支持的自定义属性如下:
<declare-styleable name="IndicatorView"> <!-- 设置指示器显示的总个数 --> <attr name="indicator_count" format="integer" /> <!-- 指示器绘图的默认颜色 --> <attr name="indicator_color" format="reference|color" /> <!-- 指示器绘图的select形式,会覆盖indicator_color设置的值--> <attr name="indicator_drawable" format="reference" /> <!-- 指示器绘图的半径 --> <attr name="indicator_radius" format="reference|dimension" /> <!-- 指示器绘图的选中时放缩比例 --> <attr name="indicator_select_scale" format="float" /> <!-- 指示器默认选中的单元 --> <attr name="indicator_select" format="integer" /> <!-- 指示器单元的宽高 优先级高于绘图的半径--> <attr name="indicator_unit_width" format="reference|dimension" /> <attr name="indicator_unit_height" format="reference|dimension" /> <!-- 指示器单元之间的间距 --> <attr name="indicator_padding" format="reference|dimension" /> </declare-styleable>
例如indicator_drawable属性支持StateListDrawable类型选择器,IndicatorView会根据不同的条件展示不同的图形。 支持如下几对的触发条件:
- state_selected
- state_pressed
- state_checked
- state_enabled
使用方式:
indicator_unit_select1.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="false"> <shape android:shape="oval"> <solid android:color="#ff0000" /> </shape> </item> <item android:state_pressed="true"> <shape android:shape="oval"> <stroke android:width="1dp" android:color="#ff0000" /> </shape> </item> </selector>
布局文件
<cn.junhua.android.view.IndicatorView android:id="@+id/indicator_view1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" app:indicator_count="9" app:indicator_drawable="@drawable/indicator_unit_select1" app:indicator_select="0" />
关联操作:
IndicatorView indicator_view = (IndicatorView) findViewById(R.id.indicator_view); indicator_view.setCount(resList.size()); //关联ViewPager indicator_view.setupWithViewPager(viewpager); //或者使用 indicator_view.setSelect(int pos);
使用动画:
private class ScaleIndicatorTransformer extends IndicatorView.TranslationIndicatorTransformer { @Override public void transformPage(IndicatorView page, Canvas canvas, int position, float positionOffset) { super.transformPage(page, canvas, position, positionOffset); Log.d(TAG, "transformPage() called with: position = [" + position + "], positionOffset = [" + positionOffset + "]"); Rect bounds = page.getUnitBounds(); float pos = Math.abs(positionOffset - 0.5f) * 2; pos = pos < 0.4f ? 0.4f : pos; canvas.scale(pos, pos, bounds.centerX(), bounds.centerY()); } } indicator_view.setIndicatorTransformer(new ScaleIndicatorTransformer()); //或者使用内置平移动画 indicator_view.setIndicatorTransformer(new IndicatorView.TranslationIndicatorTransformer());
不同的选择效果都可以通过不同的选择器得到。
欢迎Pull Requests 和 Issues。
下步更新计划:
- 在同一个指示器中支持同时显示不同StateListDrawable