APP引导页滑动实现

app的引导页很多都是用viewpager做的,小面还有一个小圆点,会根据页面切换,但是有些app引导页的小圆点会随着页面的滑动而滑动,而不是机器式的直接跳到下一页.
上图:
APP引导页滑动实现_第1张图片
APP引导页滑动实现_第2张图片
APP引导页滑动实现_第3张图片
简单做法:

  • 写布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_guide"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    android.support.v4.view.ViewPager>

    
    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始体验"
        android:textSize="24dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:padding="20dp"
        android:visibility="invisible"
        android:background="@drawable/selector_guidebutton"
        />
    
    <RelativeLayout
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_marginBottom="40dp"
        android:layout_height="wrap_content">
    
       <LinearLayout
           android:gravity="center"
           android:id="@+id/ll_guide_point"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="horizontal">

       LinearLayout>
        
        <View
            android:id="@+id/v_red_point"
            android:background="@drawable/shape_guide_point_red"
            android:layout_width="10dp"
            android:layout_height="10dp"
            />
    RelativeLayout>
RelativeLayout>
  • viewpager部分就不写了,很简单,一个适配器搞定,主要是小圆点部分,注意几点

    • 动态初始化下面的小白点
//小圆点的数量等于图片的数量
        for (int i = 0; i < imageIds.length; i++) {
            //初始化小白点
            View view = new View(ll_guide_point.getContext());
            view.setBackgroundResource(R.drawable.shape_guide_point_darker_gray);
            //创建小白点大小,这里注意把 dx 通过工具类转成 dp 
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(DensityUtils.dip2px(this,10),DensityUtils.dip2px(this,10));
            if (i > 0){
                //除了第一个小白点之外,其余都有margin
                params.leftMargin = DensityUtils.dip2px(this,8);
            }
            //将大小设置上去
            view.setLayoutParams(params);
            //将小圆点加到布局上
            ll_guide_point.addView(view);
        }
  • 设置滑动监听
 //滑动监听

    /**
     * 滑动事件
     * @param position  当前位置
     * @param positionOffset  百分比
     * @param positionOffsetPixels  移动距离
     */
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //positionOffset 移动的百分比,只需要知道两个点之间的距离,相乘就知道此时小圆点该移动多少距离
        //必须加上后面的一部分,不然你滑倒第二个的时候小红点又会回到第一个,因为此时positionOffset归0了
        float len = distance * positionOffset + position * distance;
        //让小圆点动起来,就是修改 MarginLeft
        View view = (View) findViewById(R.id.v_red_point);
        //拿到它原本的params
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
        layoutParams.leftMargin = (int) len;
        view.setLayoutParams(layoutParams);
    }

    //被选中时
    @Override
    public void onPageSelected(int position) {
        //最后一个页面被选中时让开始按钮展现出来
        if(position == imageIds.length-1){
            btn_start.setVisibility(View.VISIBLE);
        }else {
            btn_start.setVisibility(View.INVISIBLE);
        }
    }

    //滑动状态改变
    @Override
    public void onPageScrollStateChanged(int state) {

    }
  • 这里注意测量两个圆点的距离,就是上面的distance,必须要在activity的视图树全部创建完成才能测量,写在onCreate()方法中是没有效的,所以要注册观察者
  //算出第一个小圆点和第二个小圆点之间的距离,注意在oncreate方法中不能测量view的位置,因为此时界面还未绘制
        //注册一个观察者,当视图树加载完成后,调用此方法
        ll_guide_point.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            //当layout执行结束之后,回调次方法
            @Override
            public void onGlobalLayout() {
                //一旦绘制完成,取消这个监听,这个方法已经过时,但是新方法必须在API16以上才能用
                ll_guide_point.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                //此时就能拿到距离了
                distance = ll_guide_point.getChildAt(1).getLeft() - ll_guide_point.getChildAt(0).getLeft();
            }
        });

好了,上面都是主要步骤,只要掌握就能做出上面图片的那种效果了

你可能感兴趣的:(Android技术点)