我们从AndroidManifest.xml文件中看到有这么一段。
<activity android:name=".activity.SplashscreenActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"></action> <category android:name="android.intent.category.LAUNCHER"></category> </intent-filter> </activity>
知道欢迎界面为SplashscreenActivity,然后我们再来看看其类结构,以及依赖项,如下:
我们可以看到有一个showTutorial()方法来弹出软件说明对话框,以及Animation,Handler,Runnable等属性,用来产生动画,以及动画后与主UI线程通信。
首先我们来看OnCreate方法
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.splashscreen); findViewById(R.id.splashlayout); endAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out); endAnimation.setFillAfter(true); endAnimationHandler = new Handler(); endAnimationRunnable = new Runnable() { @Override public void run() { findViewById(R.id.splashlayout).startAnimation(endAnimation); } }; endAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { HomeActivity.launch(SplashscreenActivity.this); SplashscreenActivity.this.finish(); } }); showTutorial(); }
首先通过AnimationUtils.loadAnimation静态方法加载anim下的淡出动画文件fade_out,并设置动画完成后填充(这里还未播放动画)。
然后通过一个定义Runnable对象,在线程中开始这个动画,同时添加动画监听。回调方法有:onAnimationStart,onAnimationRepeat,onAnimationEnd。(这里还未开启线程)。
当然它直接调用了showTutorial();弹出软件说明对话框。
final void showTutorial() { boolean showTutorial = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_RUN_PREFERENCE, true); if (showTutorial) { final TutorialDialog dlg = new TutorialDialog(this); dlg.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { CheckBox cb = (CheckBox) dlg.findViewById(R.id.toggleFirstRun); if (cb != null && cb.isChecked()) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SplashscreenActivity.this); prefs.edit().putBoolean(FIRST_RUN_PREFERENCE, false).commit(); } endAnimationHandler.removeCallbacks(endAnimationRunnable); endAnimationHandler.postDelayed(endAnimationRunnable, 2000); } }); dlg.show(); } else { endAnimationHandler.removeCallbacks(endAnimationRunnable); endAnimationHandler.postDelayed(endAnimationRunnable, 1500); } }
看到boolean showTutorial = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_RUN_PREFERENCE, true);这一句,从Preference中得到共享的全局配置信息,这里是保存是否弹出对话框。
至于PreferenceManager怎么使用,可以参考下我的一篇Preference设置文章。主要是以键值对方式保存值。
然后实例化对话框TutorialDialog,并且添加关闭对话框setOnDismissListener监听,在关闭对话框时候触发回调,我们再回调函数public void onDismiss(DialogInterface dialog)中,可以看到首先获取是否选中选项并且保存到Preference中,然后移除回调endAnimationRunnable,同时执行了endAnimationRunnable线程。
这里的执行方法是:endAnimationHandler.postDelayed(endAnimationRunnable, 2000); 就是间隔2秒后执行我们的线程,通过Handler执行。
执行线程,在线程中我们重写它的run方法,在这个方法中,我们可以看到它执行的是播放anim动画。
同时在播放动画完毕后,跳转到另外一个界面,就是我们的主界面。HomeActivity
@Override public void onAnimationEnd(Animation animation) { HomeActivity.launch(SplashscreenActivity.this); SplashscreenActivity.this.finish(); }
当然,我们可以进入这个launch方法,可以看到它都是通过Intent进行界面跳转的。
其中: intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP) 表示,开启目标activity时,会清理栈中的其他activity.
public static void launch(Context c){ Intent intent = new Intent(c, HomeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP ); c.startActivity(intent); }
接下来,我们看看软件说明这个对话框。
public class TutorialDialog extends Dialog { /** * @param context */ public TutorialDialog(Context context) { super(context); initialize(context); } /** * @param context * @param theme */ public TutorialDialog(Context context, int theme) { super(context, theme); initialize(context); } /** * @param context * @param cancelable * @param cancelListener */ public TutorialDialog(Context context, boolean cancelable, OnCancelListener cancelListener) { super(context, cancelable, cancelListener); initialize(context); } /** * Common initialization code */ private final void initialize(final Context context) { setContentView(R.layout.tutorial); setTitle(R.string.tutorial_title); Button mCloseButton = (Button)findViewById(R.id.closeTutorial); if (mCloseButton != null) { mCloseButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); } } }
继承之Dialog类,然后在初始化方法initialize中找到相关的内容以及标题,并设置Button按钮点击监听,在监听方法中关闭本对话框。作者封装了一系列的对话框在com.teleca.jamendo.dialog包中。
本文相关的界面如下: