Android自定义控件(实现视图树绘制指示器)

发布时间 - 2026-01-10 22:25:28    点击率:

之前写轮播条或者指示器的时候都是UI图里面直接有,这样的效果并不好,给用户的体验比较差,所以闲暇之余自己写了个指示器,可以展现出一个优雅的效果,当手指 当手指滑动的时候小圆点会跟着一点一点的滑动,当手指停下时,小红点也跟着停下来。首先我说说我实现的这个原理吧

首先在布局文件里面写上线性布局,表示底部的小圆点,方向和位置,然后再在shape里面自绘小圆点。再在代码里面里用布局写出,具体步骤如下:

1、使用LayParams给布局里面添加未选中的小圆点,例如灰色;

2、设置小红点,表示滑动后的状态。

3、获取小圆点之间的距离,这里要获取小圆点的距离不能简单地getWidth,getHeiget,这样是获取不到的 ,这里要用到视图树来观察两个点距离左侧屏幕之间的距离,然后求差获取距离。

4、在监听viewpager的时候获取两者的距离。

代码如下:

一、布局文件

<!--小红点,小圆点的滑动,具体布局在代码里面写的--> 
<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<android.support.v4.view.ViewPager 
android:id="@+id/vp_pager" 
android:layout_width="match_parent" 
android:layout_height="match_parent"/> 
<Button 
android:id="@+id/btn_start" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true" 
android:layout_centerHorizontal="true" 
android:layout_marginBottom="60dp" 
android:background="#FFF107" 
android:paddingLeft="10dp" 
android:paddingRight="10dp" 
android:textSize="20sp" 
android:text="开始体验" 
android:visibility="gone"/> 
<!--小红点,小圆点的滑动,具体布局在代码里面写的--> 
<RelativeLayout 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true" 
android:layout_centerHorizontal="true" 
android:layout_marginBottom="20dp"> 
<LinearLayout 
android:id="@+id/ll_point_group" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:orientation="horizontal"> 
</LinearLayout> 
<View 
android:id="@+id/view_red_point" 
android:layout_width="10dp" 
android:layout_height="10dp" 
android:background="@drawable/shape_guide_point_selected"/> 
</RelativeLayout> 
</RelativeLayout> 
<!--普通的圆点--> 
<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="oval" > 
<solid android:color="@android:color/darker_gray" /> 
</shape> 
<!--小红点的圆点--> 
<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="oval" > 
<solid android:color="#f00" /> 
</shape> 

二、代码

/** 
* 初始化viewpager的数据 
*/ 
private void initView() { 
int[] icons = {R.mipmap.guide1,R.mipmap.guide2,R.mipmap.guide3,R.mipmap.guide4}; 
mList = new ArrayList<>(); 
for (int i = 0; i < icons.length; i++) { 
ImageView view = new ImageView(this); 
view.setBackgroundResource(icons[i]); //只有设置了背景才能填充满屏幕 
mList.add(view); 
//设置,灰色的小圆点,表示滑动时候的状态 
View point = new View(this); 
point.setBackgroundResource(R.drawable.shape_guide_point_default); //设置背景 
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(DensityUtils.dp2px(this,10), DensityUtils.dp2px(this,10)); 
point.setLayoutParams(params); 
if (i != 0) { 
params.leftMargin = DensityUtils.dp2px(this, 10); 
} 
llpointGroup.addView(point); 
} 
} 

三、获取小红点之间的距离

/** 
* 初始化小红点之间的距离 
*/ 
private void initPoint() { 
// measure -> layout -> draw 
viewRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
//完成布局后回调该方法,该方法有可能被多次回调 
@Override 
public void onGlobalLayout() { 
viewRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
mPointWidth = llpointGroup.getChildAt(1).getLeft() - llpointGroup.getChildAt(0).getLeft(); 
} 
}); 
} 

四、让小红点联动

/** 
* viewpager的页面滑动的监听 
*/ 
private void initScrollListen() { 
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
//当页面被滑动的时候 
//参数一:当前页面的位置 参数二:偏移的百分比 参数三:偏移的距离 
@Override 
public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) { 
int leftMargin = (int) (mPointWidth * (position + positionOffset)); 
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewRedPoint.getLayoutParams(); 
lp.leftMargin = leftMargin; 
viewRedPoint.setLayoutParams(lp); 
} 
//当页面被选择 
@Override 
public void onPageSelected(int position) { 
} 
//当页面状态改变的时候 
@Override 
public void onPageScrollStateChanged(int state) { 
} 
}); 
} 

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# android  # 指示器  # 实现  # Android自定义ViewPager指示器  # Android实现仿网易新闻的顶部导航指示器  # Android应用中仿今日头条App制作ViewPager指示器  # Android应用中使用ViewPager和ViewPager指示器来制作Tab标签  # Android中自定义控件之液位指示器  # Android之IphoneTreeView带组指示器的ExpandableListView效果  # Android之带group指示器的ExpandableListView(自写)  # Android自定义View Flyme6的Viewpager指示器  # 小圆点  # 小红点  # 回调  # 都是  # 圆点  # 我说  # 有可能  # 说我  # 要用  # 然后再  # 写了  # 之余  # 停下来  # 写上  # 里用  # 展现出  # id  # ViewPager  # view  # Button 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么实现模型属性的自动加密  深圳网站制作的公司有哪些,dido官方网站?  如何在IIS7中新建站点?详细步骤解析  如何快速打造个性化非模板自助建站?  jQuery 常见小例汇总  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  如何制作一个表白网站视频,关于勇敢表白的小标题?  Laravel如何实现本地化和多语言支持?(i18n教程)  如何快速搭建自助建站会员专属系统?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  高性能网站服务器部署指南:稳定运行与安全配置优化方案  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Laravel如何使用Telescope进行调试?(安装和使用教程)  如何在阿里云购买域名并搭建网站?  简单实现Android验证码  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  微信小程序 闭包写法详细介绍  三星网站视频制作教程下载,三星w23网页如何全屏?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  如何为不同团队 ID 动态生成多个“认领值班”按钮  昵图网官方站入口 昵图网素材图库官网入口  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  教你用AI将一段旋律扩展成一首完整的曲子  Laravel怎么判断请求类型_Laravel Request isMethod用法  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  JS去除重复并统计数量的实现方法  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  Java遍历集合的三种方式  实例解析Array和String方法  Laravel怎么使用Intervention Image库处理图片上传和缩放  bootstrap日历插件datetimepicker使用方法  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Laravel如何处理异常和错误?(Handler示例)  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  Laravel如何实现API版本控制_Laravel版本化API设计方案  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  JavaScript常见的五种数组去重的方式  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  如何实现建站之星域名转发设置?  Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试