现在的大多数应用都会有一个欢迎引导页面,
需求分析:
程序安装后第一次启动:
启动页-->功能引导页-->应用主页
以后启动:
启动页-->应用主页
实现原理:
用SharedPreferences实现。
创建一个boolean的变量,默认值为true。
当判断这个变量是true的时候,说明是第一次运行,就跳转到另一个引导页面。
引导页面跳转到最后一张图片时,点击某按钮发生跳转事件,回到MainActivity,此时把变量的值改成false。
引导图效果用ViewPager可以很轻松的实现。
1.布局文件
splash.xml:
1<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 tools:context=".SplashActivity" >
6
7 <ImageView
8 android:layout_width="match_parent"
9 android:layout_height="match_parent"
10 android:adjustViewBounds="true"
11 android:background="@drawable/welcome_android"
12 android:scaleType="centerCrop" />
13
14</RelativeLayout>
guide.xml:
1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <android.support.v4.view.ViewPager
8 android:id="@+id/viewpager"
9 android:layout_width="match_parent"
10 android:layout_height="match_parent" />
11
12 <LinearLayout
13 android:id="@+id/ll"
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:layout_alignParentBottom="true"
17 android:layout_centerHorizontal="true"
18 android:layout_marginBottom="24.0dp"
19 android:orientation="horizontal" >
20
21 <ImageView
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:layout_gravity="center_vertical"
25 android:clickable="true"
26 android:padding="15.0dip"
27 android:src="@drawable/dot" />
28
29 <ImageView
30 android:layout_width="wrap_content"
31 android:layout_height="wrap_content"
32 android:layout_gravity="center_vertical"
33 android:clickable="true"
34 android:padding="15.0dip"
35 android:src="@drawable/dot" />
36
37 <ImageView
38 android:layout_width="wrap_content"
39 android:layout_height="wrap_content"
40 android:layout_gravity="center_vertical"
41 android:clickable="true"
42 android:padding="15.0dip"
43 android:src="@drawable/dot" />
44
45 <ImageView
46 android:layout_width="wrap_content"
47 android:layout_height="wrap_content"
48 android:layout_gravity="center_vertical"
49 android:clickable="true"
50 android:padding="15.0dip"
51 android:src="@drawable/dot" />
52 </LinearLayout>
53
54</RelativeLayout>
main_activity.xml默认
what_new_one.xml、what_new_two.xml、what_new_three.xml(将图片名称改下就行了):
1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent" >
5
6 <ImageView
7 android:layout_width="match_parent"
8 android:layout_height="match_parent"
9 android:layout_centerInParent="true"
10 android:adjustViewBounds="false"
11 android:focusable="true"
12 android:scaleType="centerCrop"
13 android:background="@drawable/guide_350_01" />
14
15</RelativeLayout>
what_new_four.xml:
1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent" >
5
6 <ImageView
7 android:layout_width="match_parent"
8 android:layout_height="match_parent"
9 android:layout_centerInParent="true"
10 android:adjustViewBounds="false"
11 android:background="@drawable/guide_350_04"
12 android:focusable="true"
13 android:scaleType="centerCrop" />
14
15 <ImageView
16 android:id="@+id/iv_start_weibo"
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:layout_alignParentBottom="true"
20 android:layout_centerHorizontal="true"
21 android:layout_marginBottom="108dp"
22 android:background="@drawable/whats_new_start_btn"
23 android:focusable="true" />
24
25</RelativeLayout>
MainActivity.java不变
SplashActivity.java:
1package cn.eoe.leigo.splash;
2
3import android.app.Activity;
4import android.content.Intent;
5import android.content.SharedPreferences;
6import android.os.Bundle;
7import android.os.Handler;
8import android.os.Message;
9
10/** *//**
11 *
12 * @{# SplashActivity.java Create on 2013-5-2 下午9:10:01
13 *
14 * class desc: 启动画面 (1)判断是否是首次加载应用--采取读取SharedPreferences的方法
15 * (2)是,则进入GuideActivity;否,则进入MainActivity (3)3s后执行(2)操作
16 *
17 * <p>
18 * Copyright: Copyright(c) 2013
19 * </p>
20 * @Version 1.0
21 * @Author <a href="mailto:gaolei_xj@163.com">Leo</a>
22 *
23 *
24 */
25public class SplashActivity extends Activity {
26 boolean isFirstIn = false;
27
28 private static final int GO_HOME = 1000;
29 private static final int GO_GUIDE = 1001;
30 // 延迟3秒
31 private static final long SPLASH_DELAY_MILLIS = 3000;
32
33 private static final String SHAREDPREFERENCES_NAME = "first_pref";
34
35 /** *//**
36 * Handler:跳转到不同界面
37 */
38 private Handler mHandler = new Handler() {
39
40 @Override
41 public void handleMessage(Message msg) {
42 switch (msg.what) {
43 case GO_HOME:
44 goHome();
45 break;
46 case GO_GUIDE:
47 goGuide();
48 break;
49 }
50 super.handleMessage(msg);
51 }
52 };
53
54 @Override
55 protected void onCreate(Bundle savedInstanceState) {
56 super.onCreate(savedInstanceState);
57 setContentView(R.layout.splash);
58
59 init();
60 }
61
62 private void init() {
63 // 读取SharedPreferences中需要的数据
64 // 使用SharedPreferences来记录程序的使用次数
65 SharedPreferences preferences = getSharedPreferences(
66 SHAREDPREFERENCES_NAME, MODE_PRIVATE);
67
68 // 取得相应的值,如果没有该值,说明还未写入,用true作为默认值
69 isFirstIn = preferences.getBoolean("isFirstIn", true);
70
71 // 判断程序与第几次运行,如果是第一次运行则跳转到引导界面,否则跳转到主界面
72 if (!isFirstIn) {
73 // 使用Handler的postDelayed方法,3秒后执行跳转到MainActivity
74 mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS);
75 } else {
76 mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS);
77 }
78
79 }
80
81 private void goHome() {
82 Intent intent = new Intent(SplashActivity.this, MainActivity.class);
83 SplashActivity.this.startActivity(intent);
84 SplashActivity.this.finish();
85 }
86
87 private void goGuide() {
88 Intent intent = new Intent(SplashActivity.this, GuideActivity.class);
89 SplashActivity.this.startActivity(intent);
90 SplashActivity.this.finish();
91 }
92}
93
GuideActivity.java:
1package cn.eoe.leigo.splash;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import android.app.Activity;
7import android.os.Bundle;
8import android.support.v4.view.ViewPager;
9import android.support.v4.view.ViewPager.OnPageChangeListener;
10import android.view.LayoutInflater;
11import android.view.View;
12import android.widget.ImageView;
13import android.widget.LinearLayout;
14import cn.eoe.leigo.splash.adapter.ViewPagerAdapter;
15
16/** *//**
17 *
18 * @{# GuideActivity.java Create on 2013-5-2 下午10:59:08
19 *
20 * class desc: 引导界面
21 *
22 * <p>
23 * Copyright: Copyright(c) 2013
24 * </p>
25 * @Version 1.0
26 * @Author <a href="mailto:gaolei_xj@163.com">Leo</a>
27 *
28 *
29 */
30public class GuideActivity extends Activity implements OnPageChangeListener {
31
32 private ViewPager vp;
33 private ViewPagerAdapter vpAdapter;
34 private List<View> views;
35
36 // 底部小点图片
37 private ImageView[] dots;
38
39 // 记录当前选中位置
40 private int currentIndex;
41
42 @Override
43 protected void onCreate(Bundle savedInstanceState) {
44 super.onCreate(savedInstanceState);
45 setContentView(R.layout.guide);
46
47 // 初始化页面
48 initViews();
49
50 // 初始化底部小点
51 initDots();
52 }
53
54 private void initViews() {
55 LayoutInflater inflater = LayoutInflater.from(this);
56
57 views = new ArrayList<View>();
58 // 初始化引导图片列表
59 views.add(inflater.inflate(R.layout.what_new_one, null));
60 views.add(inflater.inflate(R.layout.what_new_two, null));
61 views.add(inflater.inflate(R.layout.what_new_three, null));
62 views.add(inflater.inflate(R.layout.what_new_four, null));
63
64 // 初始化Adapter
65 vpAdapter = new ViewPagerAdapter(views, this);
66
67 vp = (ViewPager) findViewById(R.id.viewpager);
68 vp.setAdapter(vpAdapter);
69 // 绑定回调
70 vp.setOnPageChangeListener(this);
71 }
72
73 private void initDots() {
74 LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
75
76 dots = new ImageView[views.size()];
77
78 // 循环取得小点图片
79 for (int i = 0; i < views.size(); i++) {
80 dots[i] = (ImageView) ll.getChildAt(i);
81 dots[i].setEnabled(true);// 都设为灰色
82 }
83
84 currentIndex = 0;
85 dots[currentIndex].setEnabled(false);// 设置为白色,即选中状态
86 }
87
88 private void setCurrentDot(int position) {
89 if (position < 0 || position > views.size() - 1
90 || currentIndex == position) {
91 return;
92 }
93
94 dots[position].setEnabled(false);
95 dots[currentIndex].setEnabled(true);
96
97 currentIndex = position;
98 }
99
100 // 当滑动状态改变时调用
101 @Override
102 public void onPageScrollStateChanged(int arg0) {
103 }
104
105 // 当当前页面被滑动时调用
106 @Override
107 public void onPageScrolled(int arg0, float arg1, int arg2) {
108 }
109
110 // 当新的页面被选中时调用
111 @Override
112 public void onPageSelected(int arg0) {
113 // 设置底部小点选中状态
114 setCurrentDot(arg0);
115 }
116
117}
118
ViewPagerAdapter.java:
1package cn.eoe.leigo.splash.adapter;
2
3import java.util.List;
4
5import android.app.Activity;
6import android.content.Context;
7import android.content.Intent;
8import android.content.SharedPreferences;
9import android.content.SharedPreferences.Editor;
10import android.os.Parcelable;
11import android.support.v4.view.PagerAdapter;
12import android.support.v4.view.ViewPager;
13import android.view.View;
14import android.view.View.OnClickListener;
15import android.widget.ImageView;
16import cn.eoe.leigo.splash.MainActivity;
17import cn.eoe.leigo.splash.R;
18
19/** *//**
20 *
21 * @{# ViewPagerAdapter.java Create on 2013-5-2 下午11:03:39
22 *
23 * class desc: 引导页面适配器
24 *
25 * <p>
26 * Copyright: Copyright(c) 2013
27 * </p>
28 * @Version 1.0
29 * @Author <a href="mailto:gaolei_xj@163.com">Leo</a>
30 *
31 *
32 */
33public class ViewPagerAdapter extends PagerAdapter {
34
35 // 界面列表
36 private List<View> views;
37 private Activity activity;
38
39 private static final String SHAREDPREFERENCES_NAME = "first_pref";
40
41 public ViewPagerAdapter(List<View> views, Activity activity) {
42 this.views = views;
43 this.activity = activity;
44 }
45
46 // 销毁arg1位置的界面
47 @Override
48 public void destroyItem(View arg0, int arg1, Object arg2) {
49 ((ViewPager) arg0).removeView(views.get(arg1));
50 }
51
52 @Override
53 public void finishUpdate(View arg0) {
54 }
55
56 // 获得当前界面数
57 @Override
58 public int getCount() {
59 if (views != null) {
60 return views.size();
61 }
62 return 0;
63 }
64
65 // 初始化arg1位置的界面
66 @Override
67 public Object instantiateItem(View arg0, int arg1) {
68 ((ViewPager) arg0).addView(views.get(arg1), 0);
69 if (arg1 == views.size() - 1) {
70 ImageView mStartWeiboImageButton = (ImageView) arg0
71 .findViewById(R.id.iv_start_weibo);
72 mStartWeiboImageButton.setOnClickListener(new OnClickListener() {
73
74 @Override
75 public void onClick(View v) {
76 // 设置已经引导
77 setGuided();
78 goHome();
79
80 }
81
82 });
83 }
84 return views.get(arg1);
85 }
86
87 private void goHome() {
88 // 跳转
89 Intent intent = new Intent(activity, MainActivity.class);
90 activity.startActivity(intent);
91 activity.finish();
92 }
93
94 /** *//**
95 *
96 * method desc:设置已经引导过了,下次启动不用再次引导
97 */
98 private void setGuided() {
99 SharedPreferences preferences = activity.getSharedPreferences(
100 SHAREDPREFERENCES_NAME, Context.MODE_PRIVATE);
101 Editor editor = preferences.edit();
102 // 存入数据
103 editor.putBoolean("isFirstIn", false);
104 // 提交修改
105 editor.commit();
106 }
107
108 // 判断是否由对象生成界面
109 @Override
110 public boolean isViewFromObject(View arg0, Object arg1) {
111 return (arg0 == arg1);
112 }
113
114 @Override
115 public void restoreState(Parcelable arg0, ClassLoader arg1) {
116 }
117
118 @Override
119 public Parcelable saveState() {
120 return null;
121 }
122
123 @Override
124 public void startUpdate(View arg0) {
125 }
126
127}
128
源码下载