我们都知道,很多应用在安装后第一次使用都会有一个新特性显示,一个好的新特性显示,将给客户带来更好的体验,因此,当我们做一个应用的时候,不能忽视这个问题,不得不佩服微信在这方面做得很不错。今天我就来模仿微信新特性的显示,做一个小应用。

  

废话不多说,先上效果图:

Android之ViewPager显示应用新特性_android

   

Android之ViewPager显示应用新特性_体验_02

   

Android之ViewPager显示应用新特性_新特性_03

最后一张,增加了一个开门的动画效果:

Android之ViewPager显示应用新特性_viewpager_04

下面是主要的类结构:

Android之ViewPager显示应用新特性_android_05

 

LoginActivity代码:

[java]  view plain  copy

1. package com.way.viewpager;  
2.   
3. import java.util.ArrayList;  
4. import java.util.List;  
5. import java.util.Timer;  
6. import java.util.TimerTask;  
7.   
8. import android.app.Activity;  
9. import android.content.Context;  
10. import android.os.Bundle;  
11. import android.os.Handler;  
12. import android.os.Message;  
13. import android.support.v4.view.ViewPager;  
14. import android.support.v4.view.ViewPager.OnPageChangeListener;  
15. import android.view.LayoutInflater;  
16. import android.view.View;  
17. import android.view.View.OnClickListener;  
18. import android.view.animation.Animation;  
19. import android.view.animation.AnimationUtils;  
20. import android.view.animation.Animation.AnimationListener;  
21. import android.view.Window;  
22. import android.widget.ImageView;  
23.   
24. /**
25.  * 
26.  * @author way
27.  * 
28.  */  
29. public class LoginActivity extends Activity {  
30. private static final int ISNEW = 0x001;// 是否为  
31. private static final int COMPLETE = 0x002;// 新特性显示完毕  
32. private Context mContext = this;  
33. private DotMarks mDotMarks;  
34. private ImageView ivLeftImage,ivRightImage;  
35. private Handler handler = new Handler() {  
36. public void handleMessage(android.os.Message msg) {  
37. switch (msg.what) {  
38. case ISNEW:  
39. // if (WhatIsNewUtils.isFirstUse(LoginActivity.this))  
40. // {//如果是第一次使用该应用  
41.                 init();  
42. // 保存标记,下一次打开程序WhatIsNewUtils.isFirstUse(LoginActivity.this)返回的是false  
43. this);  
44. // }else{  
45. // setContentView(R.layout.activity_main);  
46. // }  
47.   
48. break;  
49. case COMPLETE:  
50. null);  
51.                 setContentView(mainView);  
52.                 Animation enterAnim = AnimationUtils.loadAnimation(mContext, R.anim.main_activity_enter_anim);  
53. true);  
54.                 mainView.startAnimation(enterAnim);  
55. break;  
56. default:  
57. break;  
58.             }  
59.         }  
60.     };  
61.   
62. @Override  
63. public void onCreate(Bundle savedInstanceState) {  
64. super.onCreate(savedInstanceState);  
65.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
66.         setContentView(R.layout.login);  
67. new Timer().schedule(new TimerTask() {  
68.   
69. @Override  
70. public void run() {  
71.                 Message msg = Message.obtain();  
72.                 msg.what = ISNEW;  
73.                 handler.sendMessage(msg);  
74.             }  
75. 2000);  
76.     }  
77.   
78. /**
79.      * 初始化新特性界面
80.      */  
81. private void init() {  
82.         LayoutInflater layoutInflater = LayoutInflater.from(mContext);  
83. null);  
84.   
85. null);  
86. null);  
87. null);  
88.         ivLeftImage = (ImageView)pageThree.findViewById(R.id.iv_left_image01);  
89.         ivRightImage = (ImageView)pageThree.findViewById(R.id.iv_left_image02);  
90.           
91.         ViewPager viewPager = (ViewPager) what_is_new  
92.                 .findViewById(R.id.view_pager);  
93. new ArrayList<View>();  
94.         viewItems.add(pageOne);  
95.         viewItems.add(pageTwo);  
96.         viewItems.add(pageThree);  
97. new WhatIsNewAdapter(viewItems));  
98.         mDotMarks = (DotMarks) what_is_new.findViewById(R.id.dot_marks);  
99. /**
100.          * 翻页监听事件,用于更新索引小图片
101.          */  
102. new OnPageChangeListener() {  
103. /**
104.              * 根据ViewPager的页面的变化来实时更新索引小图标
105.              * */  
106. public void onPageSelected(int arg0) {  
107. // 更新  
108.             }  
109.   
110. public void onPageScrolled(int arg0, float arg1, int arg2) {  
111. // TODO Auto-generated method stub  
112.             }  
113.   
114. public void onPageScrollStateChanged(int arg0) {  
115. // TODO Auto-generated method stub  
116.             }  
117.         });  
118. /**
119.          * 最后一个View添加点击事件,用于切换视图
120.          */  
121. new OnClickListener() {  
122.   
123. public void onClick(View v) {  
124. //开始动画  
125.             }  
126.         });  
127. this.setContentView(what_is_new);  
128.     }  
129. /**
130.      * 动画
131.      */  
132. private void startAnimation(){  
133.         Animation leftAnim = AnimationUtils.loadAnimation(mContext, R.anim.slide_left_anim);  
134.         Animation rightAnim = AnimationUtils.loadAnimation(mContext, R.anim.slide_right_anim);  
135. //      final Animation fadeAnim = AnimationUtils.loadAnimation(mContext, R.anim.fade_anim);  
136. true);  
137. true);  
138. new AnimationListener() {  
139.               
140. public void onAnimationStart(Animation animation) {  
141. //                  mDotMarks.startAnimation(fadeAnim);  
142.             }  
143.               
144. public void onAnimationRepeat(Animation animation) {  
145.                   
146.             }  
147.               
148. public void onAnimationEnd(Animation animation) {//动画结束  
149.                 Message msg = handler.obtainMessage();  
150.                 msg.what = COMPLETE;  
151.                 handler.sendMessage(msg);  
152.             }  
153.         });  
154.         ivLeftImage.startAnimation(leftAnim);  
155.         ivRightImage.startAnimation(rightAnim);  
156.     }  
157. }

自定义DotMarks,就是下面三个小圆点,模拟翻页效果:

[java]  view plain  copy

1. package com.way.viewpager;  
2.   
3. import android.content.Context;  
4. import android.graphics.drawable.Drawable;  
5. import android.util.AttributeSet;  
6. import android.view.LayoutInflater;  
7. import android.view.View;  
8. import android.widget.ImageView;  
9. import android.widget.LinearLayout;  
10. /**
11.  * 
12.  * @author way
13.  *
14.  */  
15. public class DotMarks extends LinearLayout {  
16. private ImageView mark_one, mark_two, mark_three;//三个小点图片  
17. private Drawable guide_focus = getResources().getDrawable(  
18. //焦点图片资源  
19. private Drawable guide_default = getResources().getDrawable(  
20. //非焦点图片资源  
21.   
22. public DotMarks(Context context) {  
23. super(context);  
24.         init(context);  
25.     }  
26.   
27. public DotMarks(Context context, AttributeSet attrs) {  
28. super(context, attrs);  
29.         init(context);  
30.     }  
31. /**
32.      * 初始化
33.      * @param context
34.      * 上下文对象
35.      */  
36. private void init(Context context) {  
37.         LayoutInflater layoutInflater = LayoutInflater.from(context);  
38. null);  
39. this.addView(dotmarks);  
40.         mark_one = (ImageView) dotmarks.findViewById(R.id.dot_mark1);  
41.         mark_two = (ImageView) dotmarks.findViewById(R.id.dot_mark2);  
42.         mark_three = (ImageView) dotmarks.findViewById(R.id.dot_mark3);  
43.           
44. //设置一个默认值  
45.         mark_one.setImageResource(R.drawable.guide_focus);  
46.         mark_two.setImageResource(R.drawable.guide_default);  
47.         mark_three.setImageResource(R.drawable.guide_default);  
48.     }  
49.   
50. /**
51.      * 
52.      * 根据传递进来的页面的索引切换小图标的显示
53.      * 
54.      * */  
55. public void updateMark(int index) {  
56. switch (index) {  
57. case 0:  
58.             mark_one.setImageDrawable(guide_focus);  
59.             mark_two.setImageDrawable(guide_default);  
60.             mark_three.setImageDrawable(guide_default);  
61. break;  
62. case 1:  
63.             mark_one.setImageDrawable(guide_default);  
64.             mark_two.setImageDrawable(guide_focus);  
65.             mark_three.setImageDrawable(guide_default);  
66. break;  
67. case 2:  
68.             mark_one.setImageDrawable(guide_default);  
69.             mark_two.setImageDrawable(guide_default);  
70.             mark_three.setImageDrawable(guide_focus);  
71. break;  
72.   
73. default:  
74. break;  
75.         }  
76.     }  
77.   
78. }

新特性适配器WhatIsNewAdapter:

[java]  view plain  copy

1. package com.way.viewpager;  
2.   
3. import java.util.List;  
4.   
5. import android.os.Parcelable;  
6. import android.support.v4.view.PagerAdapter;  
7. import android.support.v4.view.ViewPager;  
8. import android.view.View;  
9. /**
10.  * 
11.  * @author way
12.  *
13.  */  
14. public class WhatIsNewAdapter extends PagerAdapter {  
15. public List<View> mListViews;  
16.   
17. public WhatIsNewAdapter(List<View> mListViews) {  
18. this.mListViews = mListViews;  
19.     }  
20.   
21. @Override  
22. public void destroyItem(View arg0, int arg1, Object arg2) {  
23.         ((ViewPager) arg0).removeView(mListViews.get(arg1));  
24.     }  
25.   
26. @Override  
27. public void finishUpdate(View arg0) {  
28.     }  
29.   
30. @Override  
31. public int getCount() {  
32. return mListViews.size();  
33.     }  
34.   
35. @Override  
36. public Object instantiateItem(View arg0, int arg1) {  
37. 0);  
38. return mListViews.get(arg1);  
39.     }  
40.   
41. @Override  
42. public boolean isViewFromObject(View arg0, Object arg1) {  
43. return arg0 == (arg1);  
44.     }  
45.   
46. @Override  
47. public void restoreState(Parcelable arg0, ClassLoader arg1) {  
48.     }  
49.   
50. @Override  
51. public Parcelable saveState() {  
52. return null;  
53.     }  
54.   
55. @Override  
56. public void startUpdate(View arg0) {  
57.     }  
58.   
59. }

工具类WhatIsNewUtils,用来判断用户是否第一次使用该app:

[java]  view plain  copy

1. package com.way.viewpager;  
2.   
3. import android.app.Activity;  
4. import android.content.Context;  
5. import android.content.SharedPreferences;  
6.   
7. /**
8.  * 
9.  * @author way
10.  * */  
11. public class WhatIsNewUtils   
12. {  
13.   
14. private static String WHAT_IS_NEW_PRE_NAME = "what_is_new_pre_name";  
15.       
16. private static String FIRST_USE_FLAG = "first_use_flag";  
17. /**
18.       * 
19.       * 判断是否是第一次使用该应用程序
20.       * 
21.       * */  
22. public static boolean isFirstUse(Context context)  
23.     {  
24.         SharedPreferences sharedPreferences = context.getSharedPreferences(WHAT_IS_NEW_PRE_NAME, Activity.MODE_PRIVATE);  
25. boolean flag = sharedPreferences.getBoolean(FIRST_USE_FLAG, true);  
26. return flag;  
27.     }  
28.       
29. /**
30.      * 
31.      *保存第一次使用的信息
32.      * 
33.      * */  
34. public static void saveFirstUseFlag(Context context)  
35.     {  
36.         SharedPreferences sharedPreferences = context.getSharedPreferences(WHAT_IS_NEW_PRE_NAME, Activity.MODE_PRIVATE);  
37.         SharedPreferences.Editor editor = sharedPreferences.edit();  
38. false);  
39.         editor.commit();  
40.     }  
41.       
42. }

新特性的主布局文件what_is_new.xml:

[html]  view plain  copy

1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
2. xmlns:tools="http://schemas.android.com/tools"  
3. android:layout_width="fill_parent"  
4. android:layout_height="fill_parent" >  
5.   
6. <android.support.v4.view.ViewPager  
7. android:id="@+id/view_pager"  
8. android:layout_width="fill_parent"  
9. android:layout_height="fill_parent" />  
10.   
11. <com.way.viewpager.DotMarks  
12. android:id="@+id/dot_marks"  
13. android:layout_width="wrap_content"  
14. android:layout_height="wrap_content"  
15. android:layout_alignParentBottom="true"  
16. android:layout_centerHorizontal="true"  
17. android:paddingBottom="50dp" />  
18.   
19. </RelativeLayout>

三个小圆点的布局文件dot_marks.xml:

[html]  view plain  copy

1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:layout_width="match_parent"  
4. android:layout_height="match_parent"  
5. android:orientation="horizontal" >  
6.   
7.   
8. <ImageView  
9. android:id="@+id/dot_mark1"  
10. android:layout_width="wrap_content"  
11. android:layout_height="wrap_content"  
12. android:src="@drawable/guide_default" />  
13.   
14.   
15.   
16. <ImageView  
17. android:id="@+id/dot_mark2"  
18. android:layout_width="wrap_content"  
19. android:layout_height="wrap_content"  
20. android:src="@drawable/guide_default" />  
21.   
22.   
23. <ImageView  
24. android:id="@+id/dot_mark3"  
25. android:layout_width="wrap_content"  
26. android:layout_height="wrap_content"  
27. android:src="@drawable/guide_default" />  
28.   
29. </LinearLayout>

还有其他一些动画效果跟布局的文件,我就不贴出来了。