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

作者:一杯清泉 时间:2023-11-14 17:11:59 

之前写轮播条或者指示器的时候都是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) {
}
});
}

来源:http://blog.csdn.net/yoonerloop/article/details/51940612

标签:android,指示器,实现
0
投稿

猜你喜欢

  • Android列表组件ListView使用详解之动态加载或修改列表数据

    2023-10-01 16:14:38
  • 一篇文章彻底搞清楚c#中的委托与事件

    2021-09-07 02:24:03
  • 自己动手写的mybatis分页插件(极其简单好用)

    2023-11-01 18:12:09
  • 深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

    2021-07-09 06:14:19
  • 详解SpringMVC @RequestBody接收Json对象字符串

    2022-03-20 05:00:10
  • Webview实现android简单的浏览器实例代码

    2023-04-20 15:21:57
  • Java正确使用访问修饰符的姿势

    2021-10-11 09:52:50
  • Java常见的阻塞队列总结

    2022-10-03 10:12:06
  • Java为什么基本数据类型不需要进行创建对象?

    2022-03-16 08:59:03
  • C#使用round函数四舍五入的方法

    2022-01-19 04:33:57
  • 基于C++实现的哈夫曼编码解码操作示例

    2023-10-13 13:02:43
  • JAVA中Collections工具类sort()排序方法

    2021-10-22 04:56:29
  • 关于Java中finalize析构方法的作用详解

    2023-12-09 23:46:27
  • Android 消息分发使用EventBus的实例详解

    2022-12-23 06:28:28
  • WPF PasswordBox进行数据绑定方法

    2022-05-23 03:53:11
  • C语言由浅入深讲解文件的操作下篇

    2022-12-05 21:21:54
  • Java8新特性:函数式编程

    2021-12-01 03:09:02
  • java集合Collection常用方法解读

    2023-11-16 18:29:07
  • Java monitor机制使用方法解析

    2023-11-09 11:25:56
  • Spring实战之协调作用域不同步的Bean操作示例

    2023-01-23 02:48:10
  • asp之家 软件编程 m.aspxhome.com