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

 更新时间:2017年01月10日 11:07:53   作者:一杯清泉  
本文主要介绍了Android视图树绘制指示器的实现原理和具体步骤。具有一定的参考价值,下面跟着小编一起来看下吧

之前写轮播条或者指示器的时候都是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 Studio 代码无提示无颜色区分问题

    解决Android Studio 代码无提示无颜色区分问题

    这篇文章主要介绍了解决Android Studio 代码无提示无颜色区分问题,需要的朋友可以参考下
    2018-08-08
  • asynctask的用法详解

    asynctask的用法详解

    Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,本文将为您介绍asynctask的用法
    2012-11-11
  • Android事件分发机制 ViewGroup分析

    Android事件分发机制 ViewGroup分析

    这篇文章主要介绍了Android事件分发机制 ViewGroup分析,事件分发从手指触摸屏幕开始,即产生了触摸信息,被底层系统捕获后会传递给Android的输入系统服务IMS,更多相关介绍,需要的朋友可以参考一下
    2022-09-09
  • android实现动态显隐进度条

    android实现动态显隐进度条

    这篇文章主要为大家详细介绍了android实现动态显隐进度条,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • android实现菜单三级树效果

    android实现菜单三级树效果

    这篇文章主要为大家详细介绍了android实现菜单三级树效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Android开发可添加头尾的RecycleView的实现

    Android开发可添加头尾的RecycleView的实现

    这篇文章主要为大家介绍了Android开发可添加头尾的RecycleView的实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • android里面屏蔽home键/禁止Home键或者随你DIY

    android里面屏蔽home键/禁止Home键或者随你DIY

    可以先禁止Home键,再在onKeyDown里处理按键值,点然后在击Home键的时候就把程序关闭,或者随你DIY等等,感觉你可以随心所欲吧,再接再厉,希望本文可以帮助到你
    2013-01-01
  • 实现Android studio设置自动导包及自动导包快捷键

    实现Android studio设置自动导包及自动导包快捷键

    这篇文章主要介绍了实现Android studio设置自动导包及自动导包快捷键的相关资料,需要的朋友可以参考下
    2017-05-05
  • android 使用 IJKPlayer 播放视频流的实现代码

    android 使用 IJKPlayer 播放视频流的实现代码

    这篇文章主要介绍了android 使用 IJKPlayer 播放视频流,这需要借助 IAndroidIO 这个接口,也可以用于播放本地文件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Android横竖屏切换及其对应布局加载问题详解

    Android横竖屏切换及其对应布局加载问题详解

    这篇文章主要为大家详细介绍了Android横竖屏切换及其对应布局加载问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04

最新评论