我们都知道,很多应用在安装后第一次使用都会有一个新特性显示,一个好的新特性显示,将给客户带来更好的体验,因此,当我们做一个应用的时候,不能忽视这个问题,不得不佩服微信在这方面做得很不错。今天我就来模仿微信新特性的显示,做一个小应用。
废话不多说,先上效果图:
最后一张,增加了一个开门的动画效果:
下面是主要的类结构:
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>
还有其他一些动画效果跟布局的文件,我就不贴出来了。