android-jamendo源码学习(一)——SplashscreenActivity

        Jamendo是一个开源的在线音乐播放器,自己学习下这个源代码的结构和实现,在这里记录下学习过程,同时也跟大家分享下。自己也是初学者多以在此以初学者的方式记录,会比较的详细的分析整个源码(大牛们看起来可能就显得比较啰嗦了...)

        后面的文章会从程序的入口开始分析,以activity作为主线来进行分析。

        PS:由于小白我是在Ubuntu下学习的,不是太习惯,大家将就着看看吧~~~

      下面先看下jamendo目录结构:下面分别是整个项目的结构图,java代码的结构图,和资源文件的结构图。

 

      

**************************************************************************SplashscreenActivity*******************************************************

下面开始从一入口activity开始介绍,对于一个Android项目我们可以从AndroidManifest.xml清单文件中找到程序的入口。下面代码就是该程序的入口Activity:

1         <activity android:name=".activity.SplashscreenActivity">
2             <intent-filter>
3                 <action android:name="android.intent.action.MAIN"></action>//决定应用程序最先启动的
4 <category android:name="android.intent.category.LAUNCHER"></category>//决定应用程序是否显示在程序列表里 5 </intent-filter> 6 </activity>

从上面代码找到入口文件为SplashscreenActivity.java 首先看下该activity的运行图。

      

SplashscreenActivity源代码:

 1 /**
 2  * 
 3  */
 4 package com.teleca.jamendo.activity;
 5 
 6 import android.app.Activity;
 7 import android.content.DialogInterface;
 8 import android.content.SharedPreferences;
 9 import android.os.Bundle;
10 import android.os.Handler;
11 import android.preference.PreferenceManager;
12 import android.view.Window;
13 import android.view.animation.Animation;
14 import android.view.animation.Animation.AnimationListener;
15 import android.view.animation.AnimationUtils;
16 import android.widget.CheckBox;
17 
18 import com.teleca.jamendo.R;
19 import com.teleca.jamendo.dialog.TutorialDialog;
20 
21 /**
22  * @author Marcin Gil
23  *
24  */
25 public class SplashscreenActivity extends Activity {
26     public final static String FIRST_RUN_PREFERENCE = "first_run";
27     
28     private Animation endAnimation;
29     
30     private Handler endAnimationHandler;
31     private Runnable endAnimationRunnable;
32     
33     /* (non-Javadoc)
34      * @see android.app.Activity#onCreate(android.os.Bundle)
35      */
36     @Override
37     protected void onCreate(Bundle savedInstanceState) {
38         super.onCreate(savedInstanceState);
39         
40         requestWindowFeature(Window.FEATURE_NO_TITLE);//设置无标题
41         setContentView(R.layout.splashscreen);
42         findViewById(R.id.splashlayout);
43 
44         endAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out);
45         endAnimation.setFillAfter(true);
46         
47         endAnimationHandler = new Handler();
48         endAnimationRunnable = new Runnable() {
49             @Override
50             public void run() {
51                 findViewById(R.id.splashlayout).startAnimation(endAnimation);
52             }
53         };
54         
55         endAnimation.setAnimationListener(new AnimationListener() {
56             @Override
57             public void onAnimationStart(Animation animation) {    }
58             
59             @Override
60             public void onAnimationRepeat(Animation animation) { }
61             
62             @Override
63             public void onAnimationEnd(Animation animation) {
64                 HomeActivity.launch(SplashscreenActivity.this);
65                 SplashscreenActivity.this.finish();
66             }
67         });
68 
69         showTutorial();
70     }
71     
72     final void showTutorial() {
73         boolean showTutorial = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_RUN_PREFERENCE, true);
74         if (showTutorial) {
75             final TutorialDialog dlg = new TutorialDialog(this);
76             dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
77                 @Override
78                 public void onDismiss(DialogInterface dialog) {
79                     CheckBox cb = (CheckBox) dlg.findViewById(R.id.toggleFirstRun);
80                     if (cb != null && cb.isChecked()) {
81                         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SplashscreenActivity.this);
82                         prefs.edit().putBoolean(FIRST_RUN_PREFERENCE, false).commit();
83                     }
84                     endAnimationHandler.removeCallbacks(endAnimationRunnable);
85                     endAnimationHandler.postDelayed(endAnimationRunnable, 2000);
86                 }
87             });
88             dlg.show();
89 
90         } else {
91             endAnimationHandler.removeCallbacks(endAnimationRunnable);
92             endAnimationHandler.postDelayed(endAnimationRunnable, 1500);
93         }
94     }
95 }

对于android的Activity我们首先看得的onCreate方法:

1.  第40行的requestWindowFeature(Window.FEATURE_NO_TITLE);使用来设置不显示标题栏的,

  有关requestWindowFeature的使用方法可以参照http://zhanhao.iteye.com/blog/1174914

2. 有关动画的加载

  首先通过静态方法AnimationUtils.loadAnimation 加载anim下的fade_out淡出动画,然后调用setFillAfter方法:设置终止填充

  fade_out.xml文件如下

1 <?xml version="1.0" encoding="utf-8"?>
2 <set xmlns:android="http://schemas.android.com/apk/res/android"
3     android:zAdjustment="bottom" android:fillAfter="false">
4 
5     <alpha android:fromAlpha="1.0" android:toAlpha="0"
6         android:duration="400" />
7 
8 </set>

 

 这个动画只个间的透明度变化实现淡出动画从 Alpha从完全不透名 fromAlpha="1.0"到完全透明 toAlpha="0" 并设置动画的持续时间duration为400ms。

有关android动可以参看Android Animation学习笔记  

(AnimationUtils.loadAnimation详细参见开发文档loadAnimation

  (有关setFillAfter方法官方解释为:

  public void setFillAfter (boolean fillAfter)

  If fillAfter is true, the transformation that this animation performed will persist when it is finished. Defaults to false if not set. Note that this applies to individual animations and when using an   AnimationSet to chain animations.  也可参见http://book.51cto.com/art/201204/328294.htm的中文解释。

  ) 

  然后定义了一个Runnable对象endAnimationRunnable,在线程中开始这个动画,同时添加动画监听setAnimationListener。回调方法有:onAnimationStart,onAnimationRepeat,onAnimationEnd。

  在onAnimationEnd方法中调用HomeActivity.launch(SplashscreenActivity.this);进行页面跳转到主页面HomeActivity。

 1 /**
 2      * Launch Home activity helper
 3      * 
 4      * @param c context where launch home from (used by SplashscreenActivity)
 5      */
 6     public static void launch(Context c){
 7         Intent intent = new Intent(c, HomeActivity.class);
 8         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP );
 9         c.startActivity(intent);
10     }

  看到上面的launch方法可以看出launch方法也是通过Intent进行界面跳转的。

  其中: intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP) 表示,开启目标activity时,会清理栈中的其他activity.  了解更多可查看官方public Intent setFlags (int flags)

  到此只是进行了加载动画,动画线程没有启动所以动画也没有播放。

3. 接下来是这个页面最主要的一个方法 showTutorial();软件介绍说明对话框,就是看到的第一副运行图的对话框;

 1 final void showTutorial() {
 2         boolean showTutorial = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_RUN_PREFERENCE, true);
 3         if (showTutorial) {
 4             final TutorialDialog dlg = new TutorialDialog(this);
 5             dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
 6                 @Override
 7                 public void onDismiss(DialogInterface dialog) {
 8                     CheckBox cb = (CheckBox) dlg.findViewById(R.id.toggleFirstRun);
 9                     if (cb != null && cb.isChecked()) {
10                         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SplashscreenActivity.this);
11                         prefs.edit().putBoolean(FIRST_RUN_PREFERENCE, false).commit();
12                     }
13                     endAnimationHandler.removeCallbacks(endAnimationRunnable);
14                     endAnimationHandler.postDelayed(endAnimationRunnable, 2000);
15                 }
16             });
17             dlg.show();
18 
19         } else {
20             endAnimationHandler.removeCallbacks(endAnimationRunnable);
21             endAnimationHandler.postDelayed(endAnimationRunnable, 1500);
22         }
23     }

 

方法开始通过boolean showTutorial = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_RUN_PREFERENCE, true); 
使用getDefaultSharedPreferences获取 每个应用都有的一个默认的偏好文件preferences.xml中的FIRST_RUN_PREFERENCE(是否首先弹出指导页面)的值;
如果showTutorial为true则显示指导页面,false的话就直接不显示,然后通过Handler来运行进程endAnimationRunnable进行页面跳转。
详细参看PreferenceManager

当showTutorial为true需要显示指导页面时 通过final TutorialDialog dlg = new TutorialDialog(this);实例化对话框dlg;并设置setOnDismissListener监听事件
监听事件中判断如果toggleFirstRun这个checkbox是否勾选了,如果勾选后通过PreferenceManager更新偏好文件中的FIRST_RUN_PREFERENCE值为false;

最后通过endAnimationHandler.removeCallbacks(endAnimationRunnable);//首先将endAnimationRunnable移除endAnimationHandler队列
    endAnimationHandler.postDelayed(endAnimationRunnable, 1500);//设置延时启动线程
来定时启动线程来实现页面自动延时跳转;

开始提到的动画会在线程启动后开始播放动画然并在动画的监听事件onAnimationEnd中进行页面跳转
 
   
项目com.teleca.jamendo.dialog包中封装了一系列的对话框下面我们看一下这个对话框TutorialDialog:
 1 /**
 2  * Tutorial dialog
 3  * 
 4  * @author Marcin Gil
 5  */
 6 public class TutorialDialog extends Dialog {
 7 
 8     /**
 9      * @param context
10      */
11     public TutorialDialog(Context context) {
12         super(context);
13         initialize(context);
14     }
15 
16     /**
17      * @param context
18      * @param theme
19      */
20     public TutorialDialog(Context context, int theme) {
21         super(context, theme);
22         initialize(context);
23     }
24 
25     /**
26      * @param context
27      * @param cancelable
28      * @param cancelListener
29      */
30     public TutorialDialog(Context context, boolean cancelable,
31             OnCancelListener cancelListener) {
32         super(context, cancelable, cancelListener);
33         initialize(context);
34     }
35 
36     /**
37      * Common initialization code
38      */
39     private final void initialize(final Context context) {
40         setContentView(R.layout.tutorial);
41         setTitle(R.string.tutorial_title);
42         
43         Button mCloseButton = (Button)findViewById(R.id.closeTutorial);
44         if (mCloseButton != null) {
45             mCloseButton.setOnClickListener(new View.OnClickListener() {
46                 
47                 @Override
48                 public void onClick(View v) {
49                     dismiss();
50                 }
51             });
52         }
53     }
54 }

 

TutorialDialog继承自Dialog并在初始化方法initialize中设置对话框内容和标题和button监听事件,通过button来关闭该对话框。下面是TutorialDialog对话框的运行图



 
   

  我们看到该方法用了关键字final修饰下面是关于final关键字的使用:

1、final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,
  类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计为final类。 final方法不能被子类的方法覆盖,但可以被继承。 2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 3、final变量(常量) 用final修饰的成员变量表示常量,只能被赋值一次,赋值后值无法改变! final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。 从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。 另外,final变量定义的时候,可以先声明,而不给初值,这种变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。
但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

 

到此第一个Activity就分析完了~~~小白第一次写这个。。。写的不好不合适或是不对的地方大家多多指正~~~~~~

后面会根据页面跳转来逐个介绍每个Activity~~~

休息~休息一下~~~

android-jamendo源码学习(二)——HomeActivity 

转载于:https://www.cnblogs.com/zc-luckystar/archive/2013/01/14/2860024.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值