最近在做项目的时候,发现UI对ViewPager
轮播图指示器情有独钟,一会要全部是圆点,一会要全部是长条,一会要选中是长条未选中是圆点。而我们之前的指示器是纯自定义的但是只支持原点,于是前后多次修改,因此这里单独提出来这个指示器,希望能给有需要的朋友带来一些帮助。这个指示器也对阿里开源库 UltraViewPager进行了兼容,同样支持。
效果图
效果图属性说明文档
这里主要就是自定义View
了,支持的公共自定义属性有以下:
<declare-styleable name="Indicator">
<!--未选中的指示器颜色-->
<attr name="normal_color" format="reference|color" />
<!--选中的指示器颜色-->
<attr name="selected_color" format="reference|color" />
<!--指示器每个item之间的间距-->
<attr name="spacing" format="dimension" />
<!--指示器排列方向-->
<attr name="orientation" format="enum">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
<!--指示器类型 命名规则:未选中样式_选中样式-->
<attr name="style" format="enum">
<!--都是圆点-->
<enum name="circle_circle" value="0"/>
<!--都是方形-->
<enum name="rect_rect" value="1" />
<!--未选中是圆点,选中是方形-->
<enum name="circle_rect" value="2" />
</attr>
<!--都是圆点指示器半径大小-->
<attr name="circle_circle_radius" format="dimension" />
<!--都是方形指示器长度-->
<attr name="rect_rect_itemWidth" format="dimension" />
<!--都是方形指示器高度-->
<attr name="rect_rect_itemHeight" format="dimension" />
<!--都是方形指示器圆角-->
<attr name="rect_rect_corner" format="dimension" />
<!--circle_rect 模式圆点半径-->
<attr name="circle_rect_radius" format="dimension" />
<!--circle_rect 模式方形宽度-->
<attr name="circle_rect_itemWidth" format="dimension" />
<!--circle_rect 模式方形高度-->
<attr name="circle_rect_itemHeight" format="dimension" />
<!--circle_rect 模式方形圆角-->
<attr name="circle_rect_corner" format="dimension" />
</declare-styleable>
共用属性
属性 | 说明 |
---|---|
normal_color |
未选中的指示器颜色 |
selected_color |
选中的指示器颜色 |
spacing |
指示器每个item之间的间距 |
style |
枚举类型,有如下几种类型 |
样式说明
style | 说明 |
---|---|
circle_circle |
圆点指示器,对应图中第一种样式 |
rect_rect |
长条指示器,对应图中第二种样式 |
circle_rect |
指示器选中是长条,未选中是圆点,对应图中第三种样式 |
如果style
设置为 circle_circle
可设置以下属性:
属性 | 说明 |
---|---|
circle_circle_radius |
都是圆点指示器半径大小 |
如果style
设置为 rect_rect
可设置以下属性:
属性 | 说明 |
---|---|
rect_rect_itemWidth |
条形长度 |
rect_rect_itemHeight |
条形高度 |
rect_rect_corner |
条形圆角 |
如果style
设置为 circle_rect
可设置以下属性:
属性 | 说明 |
---|---|
circle_rect_radius |
未选中圆点半径 |
circle_rect_itemWidth |
选中条形长度 |
circle_rect_itemHeight |
选中条形高度 |
circle_rect_corner |
选中条形设置圆角 |
如何使用
在xml使用的话,例如图中四个轮播图的布局如下,其中第四个使用了UltraViewPager
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<!--图中第一个轮播图-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="120dp">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray" />
<com.wzh.viewpager.indicator.UIndicator
android:id="@+id/indicator1"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="10dp"
app:normal_color="#99ffffff"
app:selected_color="#ffffff"
app:spacing="16dp"
app:circle_circle_radius="3dp"
app:style="circle_circle" />
</FrameLayout>
<!--图中第二个轮播图-->
<FrameLayout
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_height="120dp">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray" />
<com.wzh.viewpager.indicator.UIndicator
android:id="@+id/indicator2"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="10dp"
app:normal_color="#99ffffff"
app:selected_color="#ffffff"
app:spacing="10dp"
app:rect_rect_itemWidth="16dp"
app:rect_rect_itemHeight="2dp"
app:style="rect_rect" />
</FrameLayout>
<!--图中第三个轮播图-->
<FrameLayout
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_height="120dp">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray" />
<com.wzh.viewpager.indicator.UIndicator
android:id="@+id/indicator3"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="10dp"
app:circle_rect_corner="3dp"
app:circle_rect_itemHeight="4dp"
app:circle_rect_itemWidth="20dp"
app:circle_rect_radius="3dp"
app:normal_color="#99ffffff"
app:selected_color="#ffffff"
app:spacing="10dp"
app:style="circle_rect" />
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:text="支持阿里开源库:UltraViewPager"
android:layout_height="wrap_content" />
<!--图中第四个轮播图-->
<FrameLayout
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_height="120dp">
<com.tmall.ultraviewpager.UltraViewPager
android:id="@+id/ultra_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
app:upv_autoscroll="3000"
app:upv_infiniteloop="true"
android:background="@android:color/darker_gray" />
<com.wzh.viewpager.indicator.UIndicator
android:id="@+id/indicator4"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="10dp"
app:circle_rect_corner="3dp"
app:circle_rect_itemHeight="4dp"
app:circle_rect_itemWidth="20dp"
app:circle_rect_radius="3dp"
app:normal_color="#99ffffff"
app:selected_color="#ffffff"
app:spacing="10dp"
app:style="circle_rect" />
</FrameLayout>
</LinearLayout>
在代码里需要关联上我们的ViewPager:
//普通ViewPager使用
...
ViewPager mViewPager1 = findViewById(R.id.viewPager1);
UIndicator uIndicator1 = findViewById(R.id.indicator1);
uIndicator1.attachToViewPager(mViewPager1);
// UltraViewPager使用
...
UltraViewPager mViewPager4 = findViewById(R.id.viewPager4);
UIndicator uIndicator4 = findViewById(R.id.indicator4);
uIndicator4.attachToViewPager(mViewPager4.getViewPager());
如何兼容 UltraViewPager
以下代码是在UIndicator
中:
/**
* 关联ViewPager
* @param viewPager
*/
public void attachToViewPager(ViewPager viewPager) {
this.viewPager = viewPager;
PagerAdapter pagerAdapter = viewPager.getAdapter();
if (pagerAdapter != null) {
//TODO 如果项目使用了阿里开源库,UltraViewPager,想要兼容需要用以下方式获取 itemCount,否则去除这个if条件
if (pagerAdapter instanceof UltraViewPagerAdapter){
//从UltraViewPagerAdapter获取真实的个数
itemCount = ((UltraViewPagerAdapter)pagerAdapter).getRealCount();
} else {
itemCount = pagerAdapter.getCount();
}
selection = viewPager.getCurrentItem() % itemCount;
checkItemCount();
}
viewPager.addOnPageChangeListener(this);
}
...
@Override
public void onPageSelected(int i) {
if (viewPager != null) {
PagerAdapter pagerAdapter = viewPager.getAdapter();
if (pagerAdapter != null) {
//这么写可以兼容循环滚动设置item数量很大的ViewPager
selection = viewPager.getCurrentItem() % itemCount;
}
}
postInvalidate();
}
结语
关于如何绘制View的这里就不再一一展开了,其实很简单,主要是计算,感兴趣的可以看一下源码,顺便Star支持下O(∩_∩)O~~
网友评论