本文主要介绍了 Android 视图树绘制指示器的实现原理和具体步骤。具有一定的参考价值,下面跟着小编一起来看下吧
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
之前写轮播条或者指示器的时候都是 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) {
- }
- });
- }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 PHPERZ!
来源: