先看一下我们要开发的界面(三张图片,滑到最后一个会出现开始体验的Button,下面的小红点会跟着一起滑动):

首先看一下布局文件:

 <?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:id="@+id/activity_guide"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context="com.coderwei.a71_zhbj.activity.GuideActivity">

     <android.support.v4.view.ViewPager
         android:id="@+id/vp_guide"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         />
     <Button
         android:layout_centerHorizontal="true"
         android:layout_alignParentBottom="true"
         android:layout_marginBottom="70dp"
         android:padding="10dp"
         android:id="@+id/start_btn"
         android:textColor="#f1eaea"
         android:background="#e71616"
         android:text="开始体验"
         android:visibility="invisible"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />

     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:layout_centerHorizontal="true"
         android:layout_marginBottom="30dp">

         <LinearLayout
             android:id="@+id/ll_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content">

         </LinearLayout>
         <ImageView
             android:id="@+id/iv_red"
             android:src="@drawable/shap_red"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content" />

     </RelativeLayout>

 </RelativeLayout>

然后就是代码了:

 public class GuideActivity extends Activity {

     private ViewPager mViewPager;
     private int[] mImageIds = new int[]{R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3};
     private ArrayList<ImageView> mImageViewList;
     private LinearLayout llContainer;
     private ImageView ivRedPoint;
     private int mPaintDis;
     private Button start_btn;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.activity_guide);
         mViewPager = (ViewPager)findViewById(R.id.vp_guide);
         llContainer = (LinearLayout) findViewById(R.id.ll_container);
         ivRedPoint = (ImageView) findViewById(R.id.iv_red);
         start_btn = (Button) findViewById(R.id.start_btn);
         initData();
         GuideAdapter adapter = new GuideAdapter();
         mViewPager.setAdapter(adapter);

         //监听布局是否已经完成  布局的位置是否已经确定
         ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
             @Override
             public void onGlobalLayout() {
                 //避免重复回调        出于兼容性考虑,使用了过时的方法
                 ivRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                 //布局完成了就获取第一个小灰点和第二个之间left的距离
                 mPaintDis =   llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();
                 System.out.println("距离:"+mPaintDis);
             }
         });

         //ViewPager滑动Pager监听
         mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
             //滑动过程中的回调
             @Override
             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                 //当滑到第二个Pager的时候,positionOffset百分比会变成0,position会变成1,所以后面要加上position*mPaintDis
                 int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
                 //在父布局控件中设置他的leftMargin边距
                 RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)ivRedPoint.getLayoutParams();
                 params.leftMargin = letfMargin;
                 ivRedPoint.setLayoutParams(params);
             }

             @Override
             public void onPageSelected(int position) {
                 System.out.println("position:"+position);
                 if (position==mImageViewList.size()-1){
                     start_btn.setVisibility(View.VISIBLE);
                 }

             }

             @Override
             public void onPageScrollStateChanged(int state) {
                 System.out.println("state:"+state);
             }
         });
     }

     private void initData(){
         mImageViewList = new ArrayList<>();
         for (int i=0; i<mImageIds.length; i++){
             //创建ImageView把mImgaeViewIds放进去
             ImageView view = new ImageView(this);
             view.setBackgroundResource(mImageIds[i]);
             //添加到ImageView的集合中
             mImageViewList.add(view);

             //小圆点    一个小灰点是一个ImageView
             ImageView pointView = new ImageView(this);
             pointView.setImageResource(R.drawable.shape);
             //初始化布局参数,父控件是谁,就初始化谁的布局参数
             LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
             if (i>0){
                 //当添加的小圆点的个数超过一个的时候就设置当前小圆点的左边距为10dp;
                 params.leftMargin=10;
             }
             //设置小灰点的宽高包裹内容
             pointView.setLayoutParams(params);
             //将小灰点添加到LinearLayout中
             llContainer.addView(pointView);
         }
     }

     class GuideAdapter extends PagerAdapter{

         //item的个数
         @Override
         public int getCount() {
             return mImageViewList.size();
         }

         @Override
         public boolean isViewFromObject(View view, Object object) {
             return view == object;
         }

         //初始化item布局
         @Override
         public Object instantiateItem(ViewGroup container, int position) {
             ImageView view = mImageViewList.get(position);
             container.addView(view);
             return view;
         }

         //销毁item
         @Override
         public void destroyItem(ViewGroup container, int position, Object object) {
             container.removeView((View)object);
         }
     }
 }

小灰点:

 <?xml version="1.0" encoding="utf-8"?>
 <shape
     android:shape="oval"
     xmlns:android="http://schemas.android.com/apk/res/android">
     <!--小灰点-->
     <solid android:color="#cccccc"/>
     <size android:width="10dp" android:height="10dp"/>

 </shape>

小红点:

 <?xml version="1.0" encoding="utf-8"?>
 <shape
     android:shape="oval"
     xmlns:android="http://schemas.android.com/apk/res/android">

     <solid android:color="#f00"/>
     <size android:width="10dp" android:height="10dp"/>
 </shape>

ViewPage都很简单,上一个博文也详细介绍了的,这里就不细说了,主要是下面的小红点跟着Pager一起走。

上面其实是三个小灰点,然后小灰点的上面有一个小红点,通过计算出第一个小灰点与第二个小灰点之间的距离,我们就可以用设置ViewPager的滑动监听,然后让小红点跟着pager一起动(改变的是父控件中的内边距)。

计算小灰点之间的距离时需要注意的是,必须等到布局位置确定下来的才能的到小灰点之间的距离(界面生成的过程 measure->layout(确定位置)->draw(activity的onCreate方法执行结束之后才会走此流程)),所以要设置layout的监听:

ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()

然后的到小灰点之间的距离:
mPaintDis =   llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();

需要注意的是这句代码:
int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
positionOffset是当前滑动的百分比,当进入第二个page的时候,值为0,
position代表当前是第几个page,从0开始,也就是说当我滑到第二个page的时候 mPaintDis*0+1*mPaintDis;

PS:思路总结:

  1、页面由 ViewPager + Button + RelativeLayout(LinearLayout + TextView)组成,
  2、LinearLayout放的是小灰点,小灰点的个数由ViewPager的个数觉得,所以LinearLayout添加小灰点的时候是与VIewPager的图片资源添加到集合是一起的。
  3、然后小红点就是一个TextView因为相对布局的原因,小红点的初始位置会和小灰点的第一个点重合,
  4、然后监听ViewPager的滑动事件,通过计算第一个和第二个小灰点的左边到LinearLayout的左边的边距差,来移动小红点的位置,但是确定位置的查体须  是布局的位置已经确定,所以我们就要监听布局是否已经确定,等确定后再去计算位置差。



 


Android开发之ViewPager做新手引导界面的更多相关文章

  1. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  2. Android开发之ViewPager

    什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...

  3. Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

    最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面 ...

  4. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  5. Android开发之ViewPager的简单使用

    ViewPager是V4包中的,如果你的编译器敲不出ViewPager,那么你就需要添加,看下面: 第一步:点击+号 第二步:选择第一个Library 第三步:添加这个包: 然后点击ok-->o ...

  6. Android开发之viewpager导报错误解决方法:错误代码 Caused by: java.lang.ClassNotFoundException: Didn't find class

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Caused by: java.lang.ClassNotFoundException: Didn't ...

  7. Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面

    现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下. 1.跳转到拨号界面,代码如下: 1)直接拨打 Intent intentPhone = new Intent ...

  8. 【Android UI】Android开发之View的几种布局方式及实践

    引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...

  9. Android开发之旅: Intents和Intent Filters(理论部分)

    引言 大部分移动设备平台上的应用程序都运行在他们自己的沙盒中.他们彼此之间互相隔离,并且严格限制应用程序与硬件和原始组件之间的交互. 我们知道交流是多么的重要,作为一个孤岛没有交流的东西,一定毫无意义 ...

随机推荐

  1. 010 使用netmap API接管网卡,接收数据包,回应ARP请求

    一.本文目的: 上一节中,我们已经在CentOS 6.7 上安装好了netmap,也能接收和发送包了,这节我们来调用netmap中的API,接管网卡,对网卡上收到的数据包做分析,并回应ARP请求. 二 ...

  2. javaScript事件(五)事件类型之鼠标事件

    一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 四.IE事件处理程序 以上内容见javaScript事件(二)事件处理程序 五.事件对象 以上内容见javaS ...

  3. [转]TCP协议中的三次握手和四次挥手(图解)

    本文转自:http://blog.csdn.net/whuslei/article/details/6667471 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来 ...

  4. 买错的电影票,含着泪也得看-LAMP搭建&Linux基础

    hi 没说过,上周五室友过生请客,在龙湖里吃嗨了喝爽了,回去的路上侃侃而谈.说好的这周一起去看年内最后的大片,火星救援的,谁知道老子眼神不好,买错了电影的时间...把周六的约定提前到了今儿个下午,ma ...

  5. Openxml入门---Openxm读取Excel数据

    Openxml读取Excel数据: 有些问题,如果当Cell 里面是 日期和浮点型的话,对应的Cell.DataType==Null,对应的时间会转换为一个浮点型,对于这块可以通过DateTime.F ...

  6. PCA原理与实践

    在对数据进行预处理时,我们经常会遇到数据的维数非常之大,如果不进行相应的特征处理,那么算法的资源开销会很大,这在很多场景下是我们不能接受的.而对于数据的若干维度之间往往会存在较大的相关性,如果能将数据 ...

  7. CSS Sprite雪碧图应用

    在写网页过程中,会遇到这种需要使用多个小图标: 如上图中的「女装」文字左边的图标.容易想到的解决方法是为每张图片加入<img>标签,但这样做会增加HTTP请求数量,影响网站加载速度.比这更 ...

  8. hdu-5492 Find a path(dp)

    题目链接: Find a path Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. 第28章 行为型模式大PK

    27.1 策略模式 VS 命令模式 27.1.1 策略模式实现压缩算法 //行为型模式大PK——策略模式和命令模式 //实例:用策略模式实现压缩算法 #include <iostream> ...

  10. IT菜鸟的3(for循环+分支语句)

    第三天学的东西感觉已经不是很容易能想通了,感觉头懵懵的,难道这就是是文科生的障碍吗,我不相信,坚持!相信自己一定会做好! 1:for循环!(1)循环四要素:初始条件,循环条件,循环体,状态改变for( ...