在我们安装完成一个新应用的时候,经常会见到由几个图片或短动画组成的启动界面,可以用手指滑动,显示完毕后可以点击进入主界面,这样的效果会给用户留下很好的印象,这个功能可以由viewPager来制作,ViewPager是一个和listView相似的控件,可以称之为引导页,之所以说他们相似,因为二者都要通过Adapter来加载数据,二者的用法同样都比较复杂,不同的是ViewPager还要创建视图集合来存放负责显示的几个View,并通过LayoutInflater将这些View都加载到布局里来。

下面就来看一下怎么使用ViewPager

一)实现ViewPager功能

1)新建GuiedActivity,作为引导界面,其对应的布局文件里把VIewPager传入,代码如下,设置其背景为黑色,注意不是系统控件,所以要写上全部包名

<?xml version="1.0" encoding="utf-8"?>
<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/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        >
        
    </android.support.v4.view.ViewPager>
</RelativeLayout>


2)新建ViewPagerAdapter继承PagerAdapter,这里写了泛型为view的集合来存放几个view,,并通过removeView()和addView()来将其移除和添加到布局,这几个view里将会在引导界面加载我们要显示的图片,最下面是重写了父类方法

public class ViewPagerAdapter extends PagerAdapter {
	
	private List<View> views;
	private Context context;
	
	public ViewPagerAdapter(Context context,List<View> views) {
		this.context=context;
		this.views=views;
	}

	@Override
	public void destroyItem(View container, int position, Object object) {
		((ViewPager) container).removeView(views.get(position));//取消view
	}
	
	@Override
	public Object instantiateItem(View container, int position) {
		
		((ViewPager) container).addView(views.get(position));//获取到view
		return views.get(position);
	}

	@Override
	public int getCount() {
		return views.size();
	}

	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return (arg0==arg1);  //判断当前的view是不是我们需要的对象
	}
	
	
}






3)

在引导界面里通过LayoutInflater的inflater完成view的加载,然后将加载完成的view添加到views集合里去,把views作为数据传入到适配器的参数里,最后让VeiwPager加载其适配器即可

public class GuideActivity extends Activity implements OnPageChangeListener{
	private ViewPager vp;
	private ViewPagerAdapter vpa;
	private List<View> views;
@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout. guiedlayout);
		initView();
}
         private void initView() {
         LayoutInflater inflater=LayoutInflater.from(this);
         views=new ArrayList<View>();
         
         views.add(inflater.inflate(R.layout.one,null));
         views.add(inflater.inflate(R.layout.two,null));
         views.add(inflater.inflate(R.layout.three,null));
         
         vpa=new ViewPagerAdapter(this, views);
         vp=(ViewPager) findViewById(R.id.viewpager);
         vp.setAdapter(vpa);
         }
}



这里面的加载的三个布局源代码如下,很简单,只是放了一个图片,其他的两个只改变了图片资源,因此只要贴上来一个就好:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ImageView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/guide_1"
    />
</LinearLayout>



这样,一个能够显示三张图片的引导页的功能就完成了,可以往右滑动图片,我们实际使用中在滑动的时候会发现,界面的下方一般都有三个小点,当屏幕显示哪一个视图,哪一个小点就会亮一些,下面我们来实现这个功能



二)添加导航点

1)首先当然是配置布局文件,在guied对应的布局里将小点加进来,每一个小点是一个图片,将它们水平排列在一个LinearLayout放在布局文件里

<?xml version="1.0" encoding="utf-8"?>
<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/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        >
        
    </android.support.v4.view.ViewPager>


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >


        <ImageView
            android:id="@+id/iv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/login_point_selected" />


        <ImageView
            android:id="@+id/iv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/login_point" />


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


</RelativeLayout>




2)把小点放在一个数组dots[]里,把他们的id都传进一个数组ids[]里

private ImageView dots[];
	private int Ids[]={R.id.iv1,R.id.iv2,R.id.iv3};


然后写一个方法,把所有的点对应的图片都加载进来,别忘了在onCreate方法里引用这个方法哦


private void initDots(){
    	dots=new ImageView[views.size()];  //设置点的个数与view的个数相同
    	for(int i=0;i<views.size();i++){
    		dots[i]=(ImageView)findViewById(Ids[i]);  //加载点的id
    	}
    }



这个时候我们应该想到,现在仅仅是把小点都加载进来了,他们是会显示在引导界面没有错,但是滑动图片小点并不会变化,

那么怎么才能让我们当前的View对应的小点是高亮的那个图片呢,肯定要监听引导页的变化啊,让我们的类实现引导页变化的事件监听接口

public class GuideActivity extends Activity implements OnPageChangeListener
之后下面的三个方法会出现在类里面,分别对应着三个不同的状态,改变状态,滑动状态,当选状态,在当选状态里,如果当前页的id和小点的id一样,那么小点加载为高亮的那个图片即可实现我们的功能。

@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onPageSelected(int arg0) {
        		for(int i=0;i<views.size();i++){
        			if(arg0==i){
        				dots[i].setImageResource(R.drawable.login_point_selected);
        			}else{
        				dots[i].setImageResource(R.drawable.login_point);
        			}
        		}
	}



引导页的功能已经都完成了,那么我们要转到主界面,当然还要在最后的那个view里加一个按钮点击事件啦

三)添加进入主界面按钮

1)在第三个view里加上按钮,按钮通过LinearLayout放在布局里

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ImageView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/guide_3"
    />

<LinearLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:layout_alignParentBottom="true"
    >
<pre name="code" class="java"><Button
    android:id="@+id/start_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:text="开始体验" />

</LinearLayout></RelativeLayout>



2)接下来在代码里为按钮添加事件,当前为guied活动,所以不能直接加载按钮的id,通过views.get(3)来加载,也就是我刚才把按钮放在那个布局里的地方

start=(Button) views.get(2).findViewById(R.id.start_btn);//注意这里要从views里获取按钮的实例
         start.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent i=new Intent(GuideActivity.this,MainActivity.class);
				startActivity(i);
				finish();
			}
		});




四)我们在实际使用应用的时候会发现,引导页一般只会在第一次安装出现,其他时候打开是没有引导页的,这样避免了用户每次打开应用都要看一遍图片,再好看的图片用户看多了都会厌烦的,其他时候打开一般只有一个启动画面,上面有应用图标的一个图片,这个功能的实现按照下面的步骤来:

1)新建welcome活动,作为启动界面,其布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ImageView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/welcome_android"
    />
</LinearLayout>


2)

我们让启动画面有个几秒的时候给主机开启应用的缓冲时间,自然这里的延迟时间不能在主线程进行,通过Handler的回调来完成。

怎么才能知道是不是第一次安装呢?我们设置一个boolean类型的数据isFirst,  给它赋初值为false,然后在onCreate的时候判断其是否存在。

SharedPreferences来获取并且默认返回值为true,如果不存在,就会返回true,我们让其值为true的时候进入引导页,然后再通过preferences.edit()给其写上isFirst,同时指定为false,这样以后再打开程序,就会获取到有这个isFirst存在,且值为false,我们让其为false的时候进入启动界面

public class Welcome extends Activity{


	public static final int TIME=3000;
	public static final int GOGUIED=1000;
	public static final int GOHOME=1001;
	private boolean isFirst=false;
	
	private Handler mHander=new Handler(){
		public void handleMessage(android.os.Message msg){
			switch (msg.what) {
			case GOHOME:
				goHome();
				break;
			case GOGUIED:
				goGuied();
				break;
			default:
				break;
			}
		}
	};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.welcome);
		init();
	}
	
	
	private void init(){
		SharedPreferences preferences=getSharedPreferences("liujiawei",MODE_PRIVATE);
		isFirst=preferences.getBoolean("isFirst",true); //如果没有isFirst,默认的返回是true
		if(isFirst){
			mHander.sendEmptyMessageDelayed(GOGUIED, TIME); //如果是第一次,到引导界面
			
			/*第一次进入引导界面之后,在这里存储isFirst的值,以后再打开程序就有了isFirst的值
			 * 就会进入主界面*/
			
			Editor editor=preferences.edit(); 
			editor.putBoolean("isFirst", false);
			editor.commit();
			
		}else{
			mHander.sendEmptyMessageDelayed(GOHOME, TIME);
		}
	}
	
	private void goHome(){
		Intent i=new Intent(Welcome.this,MainActivity.class);
		startActivity(i);
		finish();
	}
	private void goGuied(){
		Intent i=new Intent(Welcome.this,GuideActivity.class);
		startActivity(i);
		finish();
	}


}