Android ViewPager指示器

一个values文件

attrs_universal_indicator.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources><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>
</resources>

 

 

自定义view类UIndicator

/*** 作者:created by meixi* 邮箱:1085220040@qq.com* 日期:2020/1/6 10:41*/public class UIndicator extends View implements ViewPager.OnPageChangeListener {private static final String TAG = "UIndicator";//指示器样式一 选中未选中都是圆点public static final int STYLE_CIRCLR_CIRCLE = 0;//指示器样式二 选中未选中都是方形public static final int STYLE_RECT_RECT = 1;//指示器样式三 选中方形,未选中圆点public static final int STYLE_CIRCLR_RECT = 2;//横向排列public static final int HORIZONTAL = 0;//纵向排列public static final int VERTICAL = 1;private Context mContext;//指示器之间的间距private int spacing;//指示器排列方向private int orientation = HORIZONTAL;//选中与为选中的颜色private ColorStateList selectedColor, normalColor;//指示器样式,默认都是圆点private int mStyle = STYLE_CIRCLR_CIRCLE;//样式一 圆点半径大小private int circleCircleRadius = 0;//样式二 方形大小及圆角private int rectRectItemWidth = 0, rectRectItemHeight = 0, rectRectCorner = 0;//样式三 选中的方形大小及圆角private int circleRectItemWidth = 0, circleRectItemHeight = 0, circleRectCorner = 0;//样式三 未选中的圆点半径private int circleRectRadius = 0;//画笔private Paint normalPaint, selectedPaint;//指示器item的区域private RectF mRectF;//指示器大小private int width, height;//指示器item个数private int itemCount = 0;//当前选中的位置private int selection = 0;private ViewPager viewPager;public UIndicator(Context context) {this(context, null);}public UIndicator(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public UIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;init(attrs);intPaint();checkItemCount();}/*** 加载自定义属性*/private void init(AttributeSet attrs) {// 加载自定义属性集合TypedArray ta = mContext.obtainStyledAttributes(attrs, R.styleable.Indicator);// 第二个参数是默认设置颜色selectedColor = ta.getColorStateList(R.styleable.Indicator_selected_color);normalColor = ta.getColorStateList(R.styleable.Indicator_normal_color);spacing = ta.getDimensionPixelSize(R.styleable.Indicator_spacing, dip2px(6));//6orientation = ta.getInt(R.styleable.Indicator_orientation, HORIZONTAL);mStyle = ta.getInt(R.styleable.Indicator_style, STYLE_CIRCLR_CIRCLE);circleCircleRadius = ta.getDimensionPixelSize(R.styleable.Indicator_circle_circle_radius, dip2px(3));rectRectCorner = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_corner, 0);rectRectItemHeight = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_itemHeight, dip2px(3));rectRectItemWidth = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_itemWidth, dip2px(15));circleRectCorner = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_corner, 0);circleRectRadius = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_radius, dip2px(3));//3circleRectItemHeight = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_itemHeight, dip2px(3));circleRectItemWidth = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_itemWidth, dip2px(15));// 解析后释放资源ta.recycle();}private void intPaint() {normalPaint = new Paint();normalPaint.setStyle(Paint.Style.FILL);normalPaint.setAntiAlias(true);normalPaint.setColor(normalColor == null ? Color.GRAY : normalColor.getDefaultColor());selectedPaint = new Paint();selectedPaint.setStyle(Paint.Style.FILL);selectedPaint.setAntiAlias(true);selectedPaint.setColor(selectedColor == null ? Color.RED : selectedColor.getDefaultColor());mRectF = new RectF();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);switch (mStyle) {case STYLE_CIRCLR_CIRCLE:if (orientation == HORIZONTAL){width = 2 * circleCircleRadius * itemCount + (itemCount - 1) * spacing;height = Math.max(heightSize, 2 * circleCircleRadius);} else {height = 2 * circleCircleRadius * itemCount + (itemCount - 1) * spacing;width = Math.max(widthSize, 2 * circleCircleRadius);}break;case STYLE_RECT_RECT:if (orientation == HORIZONTAL){width = rectRectItemWidth * itemCount + (itemCount - 1) * spacing;height = Math.max(heightSize, rectRectItemHeight);} else {height = rectRectItemHeight * itemCount + (itemCount - 1) * spacing;width = Math.max(widthSize, rectRectItemWidth);}break;case STYLE_CIRCLR_RECT:if (orientation == HORIZONTAL){int normalItemWidth = circleRectRadius * 2;width = (itemCount - 1) * normalItemWidth + circleRectItemWidth + (itemCount - 1) * spacing;int tempHeight = Math.max(circleRectItemHeight, circleRectRadius * 2);height = Math.max(heightSize, tempHeight);} else {int normalItemHeight = circleRectRadius * 2;height = (itemCount - 1) * normalItemHeight + circleRectItemHeight + (itemCount - 1) * spacing;int tempWidth = Math.max(circleRectItemWidth, circleRectRadius * 2);width = Math.max(widthSize, tempWidth);}break;}setMeasuredDimension(width, height);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (orientation == HORIZONTAL) {switch (mStyle) {case STYLE_CIRCLR_CIRCLE:float cy = height / 2;for (int i = 0; i < itemCount; i++) {int cx = (i + 1) * circleCircleRadius + i * spacing;//全部绘制圆点,画笔的区别canvas.drawCircle(cx, cy, circleCircleRadius, i == selection ? selectedPaint : normalPaint);}break;case STYLE_RECT_RECT:for (int i = 0; i < itemCount; i++) {int left = i * rectRectItemWidth + i * spacing;mRectF.set(left, 0, left + rectRectItemWidth, rectRectItemHeight);//全部绘制圆角矩形,画笔的区别canvas.drawRoundRect(mRectF, rectRectCorner, rectRectCorner, i == selection ? selectedPaint : normalPaint);}break;case STYLE_CIRCLR_RECT:for (int i = 0; i < itemCount; i++) {int left = selection * (circleRectRadius * 2 + spacing);int top;if (selection == i) {//选中的绘制圆角矩形top = (height - circleRectItemHeight) / 2;mRectF.set(left, top, left + circleRectItemWidth, circleRectItemHeight + top);canvas.drawRoundRect(mRectF, circleRectCorner, circleRectCorner, selectedPaint);} else {//未选中的绘制圆点,距离需要判断position在选中的左边或者右边,从而确定cxtop = (height - circleRectRadius * 2) / 2;int cx = 0;float cy1 = circleRectRadius + top;if (selection < i) {cx = (i - 1) * circleRectRadius * 2 + i * spacing + circleRectItemWidth + circleRectRadius;} else {cx = i * (circleRectRadius * 2) + i * spacing + circleRectRadius;}canvas.drawCircle(cx, cy1, circleRectRadius, normalPaint);}}break;}} else {switch (mStyle) {case STYLE_CIRCLR_CIRCLE:float cx = width / 2;for (int i = 0; i < itemCount; i++) {int cy = i * (circleCircleRadius * 2 + spacing)+ circleCircleRadius;//全部绘制圆点,画笔的区别canvas.drawCircle(cx, cy, circleCircleRadius, i == selection ? selectedPaint : normalPaint);}break;case STYLE_RECT_RECT:for (int i = 0; i < itemCount; i++) {int top = i * rectRectItemHeight + i * spacing;int left = (width - rectRectItemWidth) / 2;mRectF.set(left, top, left + rectRectItemWidth, top + rectRectItemHeight);//全部绘制圆角矩形,画笔的区别canvas.drawRoundRect(mRectF, rectRectCorner, rectRectCorner, i == selection ? selectedPaint : normalPaint);}break;case STYLE_CIRCLR_RECT:for (int i = 0; i < itemCount; i++) {if (selection == i) {int left = (width - circleRectItemWidth) / 2;//选中的绘制圆角矩形int top = selection * (circleRectRadius * 2 + spacing);mRectF.set(left, top, left + circleRectItemWidth, top + circleRectItemHeight);canvas.drawRoundRect(mRectF, circleRectCorner, circleRectCorner, selectedPaint);} else {//未选中的绘制圆点,距离需要判断position在选中的左边或者右边,从而确定cxint cx1 = (width - 2 * circleRectRadius) / 2 + circleRectRadius;float cy1 = 0;if (selection < i) {cy1 = (i - 1) * circleRectRadius * 2 + i * spacing + circleRectItemHeight + circleRectRadius;} else {cy1 = i * (circleRectRadius * 2) + i * spacing + circleRectRadius;}canvas.drawCircle(cx1, cy1, circleRectRadius, normalPaint);}}break;}}}/*** 关联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);}/*** 设置选中的值,当ViewPager只有一个item不显示指示器*/private void checkItemCount() {if (selection >= itemCount) {selection = itemCount - 1;}setVisibility((itemCount <= 1) ? GONE : VISIBLE);}@Overridepublic void onPageSelected(int i) {if (viewPager != null) {PagerAdapter pagerAdapter = viewPager.getAdapter();if (pagerAdapter != null) {selection = viewPager.getCurrentItem() % itemCount;}}postInvalidate();}@Overridepublic void onPageScrolled(int i, float v, int i1) {}@Overridepublic void onPageScrollStateChanged(int i) {}/*** dp to px*/public int dip2px(float dpValue) {final float scale = getContext().getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}
}

Activity代码

 

public class ViewPagerActivity extends Activity {private ViewPager vp;private UIndicator uIndicator1;

 

vp = findViewById(R.id.vp_guide);
uIndicator1 = findViewById(R.id.indicator1);
uIndicator1.attachToViewPager(vp);

vp.setAdapter(mAdapter);在attachToViewPager之前

 

附:layout调用自定义view

<com.tianxin.okhttptest.viewpg.UIndicatorandroid:id="@+id/indicator1"android:layout_width="match_parent"android:layout_height="6dp"android:layout_gravity="bottom|center_horizontal"android:layout_marginTop="10dp"app:circle_circle_radius="3dp"app:normal_color="#99ffffff"app:selected_color="#ffffff"app:spacing="10dp"app:style="circle_rect" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试数据生成工具

测试数据生成工具 备忘几个测试数据生成工具: DataFactory是一种强大的数据产生器&#xff0c;拥有图形界面,它允许开发人员和QA很容易产生百万行有意义的正确的测试数据库,该工具支持DB2、Oracle、Sybase、SQL Server数据库&#xff0c;支持ODBC连接方式&#xff0c;无法直接使…

Hibernate--使用xml配置映射关系

写在前面&#xff1a; 配置实体类与数据库的映射关系&#xff0c;有两种方式&#xff1a; 1.使用*.hbm.xml 2.使用注解 二&#xff1a;xml的配置方式&#xff1a; eg:员工的xml配置文件: <?xml version"1.0" encoding"UTF-8"?> <!DOCTYP…

工作137:map函数

1状态管理定义 2设置数值

小程序 background-image背景图片设置的注意点

微信小程序通过background-image设置背景&#xff1a;只支持线上图片和base64图片&#xff0c;不支持本地图片&#xff1b;base64图片设置步骤如下&#xff1a; 1.在网站http://imgbase64.duoshitong.com/上将图片转成base64格式的文本 2.在WXSS中使用以上文本&#xff1a;ba…

能走多远不取决于一个人改正多少个缺点,而在于是否最大限度发挥长处

老总分享的文章&#xff0c;文章观点很独特&#xff0c;但不知道具体出处&#xff0c;内容如下&#xff1a; 能走多远不取决于一个人改正多少个缺点&#xff0c;而在于是否最大限度发挥长处。 两个性格迥异CEO的不同结局&#xff1a; 某人投资的两家公司的CEO性格迥异。 A是近乎…

mpvue 中使用 wx-f2 tooltip 失效解决

直接贴出解决方案&#xff0c;需要在vue文件里面拷贝f2-canvas.js里面的代码&#xff1a; F2.Util.addEventListener function (source, type, listener) {source.addListener(type, listener); }; F2.Util.removeEventListener function (source, type, listener) {source.…

java从Object类型转换成double类型

java从Object类型转换为double类型&#xff1a; Map<String,Object> map new HashMap<String,Object>(); map.put("order",1.245); BigDecimal order (BigDecimal)map.get("order"); double d (ordernull?0:order.doubleValue()); 转载于:…

工作138:git使用

可以直接拉取代码

windows 2008 远程桌面如何设置允许多用户登录?

今天又遇到一问题&#xff0c;公司的服务器&#xff0c;就是Windows server 2008系统默认只支持一个administrator用户登陆&#xff0c;一个登录后另一个就被踢掉了&#xff0c;有没有办法像Windows Server 2003那样允许多用户用同时同一个用户名登录?  这是网上查的解决方…

Activity嵌套fragment大全,activity加载单个fragment,TabLayout+ViewPager实现多个fragment滑动效果

加载单个fragment效果 头部标题多个fragment 底部标题按钮多个fragment 底部标题按钮多个fragment FragmentPagerAdapter实现&#…

微信公众号 自定义菜单栏目

我的核心写法&#xff0c;使用node 官方文档地址 https://mp.weixin.qq.com/wiki?tresource/res_main&idmp1421141013 import * as client from superagent;const createMenu async function () {// ts-ignorelet access_token await this.getGlobalToken();const url …

实验二实验报告

实验过程 实验2.1 实验内容&#xff1a; 参考教材p375,完成链树LinkedBinaryTree的实现&#xff08;getRight,contains,toString,preorder,postorder&#xff09;用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试&#xff0c;提交测试代码运行截图&#xff0c;要全…

ViewPager外部获取“当前显示的页面的位置position”

设置onPageChangeListener方法即可 viewPagerl.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}Overridepublic void onPageSelected(int position) {…

高效update方案

--方案1&#xff1a;如果有索引&#xff0c;先把索引删除后&#xff0c;再update&#xff0c;最后把索引重新创建一下因为索引对update影响很大。--方案2:1.create table newA as select id,name,age1 age from A;2.drop table A;3.rename newA to A--方案3:set autocommit 100…

使用cron表达式 设置定时任务

主要讲解cron表达式。其实只需要掌握6个通配符表达的意思&#xff0c;就可以了。 * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ | │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun) │ │ │ │ └───── month (1 - 12) │ │ │ └────────── day …

jmeter之录制控制器与代理的使用

jmeter之录制控制器与代理的使用 1. 先启动jmeter&#xff0c;在测试计划中添加线程组 2. 选中线程组右键添加&#xff0c;在配置元件中点击HTTP请求默认值 3. 选中线程组右键添加&#xff0c;在逻辑控制器中点击录制控制器 4. 工作台中&#xff0c;右…

工作139:生命周期

生命周期是生命周期 执行函数是执行函数 没有必然关系

为什么要进行归一化处理?(从寻找最优解这个角度讨论)

例子 假定为预测房价的例子&#xff0c;自变量为面积&#xff0c;房间数两个&#xff0c;因变量为房价。 那么可以得到的公式为&#xff1a; 其中代表房间数&#xff0c;代表变量前面的系数。 其中代表面积&#xff0c;代表变量前面的系数。 首先我们祭出两张图代表数据是否均一…

Android 获取触摸点坐标,判断滑动方向,滑动距离,滑动速度

activity 或 fragment 实现接口 View.OnTouchListener 如&#xff1a;public class MyFragment extends Fragment implements View.OnTouchListener{ 重写实现方法 Overridepublic boolean onTouch(View v, MotionEvent event) {//继承了Activity的onTouchEvent方法&#xff…