您的位置:首页 > 移动开发 > Android开发

Android启动界面之ViewPager用法详解

2016-05-13 00:17 591 查看
在我们安装完成一个新应用的时候,经常会见到由几个图片或短动画组成的启动界面,可以用手指滑动,显示完毕后可以点击进入主界面,这样的效果会给用户留下很好的印象,这个功能可以由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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: