我们从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方法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
@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();弹出软件说明对话框。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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);
}
接下来,我们看看软件说明这个对话框。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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包中。
本文相关的界面如下: