一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

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

时间:2017-01-10 编辑:简简单单 来源:一聚教程网

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

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

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

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

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

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

代码如下:

一、布局文件

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:id="@+id/vp_pager"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

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"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_centerHorizontal="true"

android:layout_marginBottom="20dp">

android:id="@+id/ll_point_group"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/view_red_point"

android:layout_width="10dp"

android:layout_height="10dp"

android:background="@drawable/shape_guide_point_selected"/>

android:shape="oval">

android:shape="oval">

二、代码

/**

* 初始化viewpager的数据

*/

privatevoidinitView() {

int[] icons = {R.mipmap.guide1,R.mipmap.guide2,R.mipmap.guide3,R.mipmap.guide4};

mList =newArrayList<>();

for(inti =0; i < icons.length; i++) {

ImageView view =newImageView(this);

view.setBackgroundResource(icons[i]);//只有设置了背景才能填充满屏幕

mList.add(view);

//设置,灰色的小圆点,表示滑动时候的状态

View point =newView(this);

point.setBackgroundResource(R.drawable.shape_guide_point_default);//设置背景

LinearLayout.LayoutParams params =newLinearLayout.LayoutParams(DensityUtils.dp2px(this,10), DensityUtils.dp2px(this,10));

point.setLayoutParams(params);

if(i !=0) {

params.leftMargin = DensityUtils.dp2px(this,10);

}

llpointGroup.addView(point);

}

}

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

/**

* 初始化小红点之间的距离

*/

privatevoidinitPoint() {

// measure -> layout -> draw

viewRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener() {

//完成布局后回调该方法,该方法有可能被多次回调

@Override

publicvoidonGlobalLayout() {

viewRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);

mPointWidth = llpointGroup.getChildAt(1).getLeft() - llpointGroup.getChildAt(0).getLeft();

}

});

}

四、让小红点联动

/**

* viewpager的页面滑动的监听

*/

privatevoidinitScrollListen() {

viewPager.setOnPageChangeListener(newViewPager.OnPageChangeListener() {

//当页面被滑动的时候

//参数一:当前页面的位置 参数二:偏移的百分比 参数三:偏移的距离

@Override

publicvoidonPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels) {

intleftMargin = (int) (mPointWidth * (position + positionOffset));

RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewRedPoint.getLayoutParams();

lp.leftMargin = leftMargin;

viewRedPoint.setLayoutParams(lp);

}

//当页面被选择

@Override

publicvoidonPageSelected(intposition) {

}

//当页面状态改变的时候

@Override

publicvoidonPageScrollStateChanged(intstate) {

}

});

}

热门栏目