android的時鐘,也就是鬧鐘應用,從桌面的widget直接點進去的會打開AlarmClock這個Activity.java
好像我日常都不上圖的,今天就上兩張圖先。android
一張是應用界面圖以下:(改天再上傳了,好像今天osc服務器有問題啊)服務器
一,初看:ide
總共有10個方法,加一個CursorAdapter的子類的內部類。佈局
其中的10個方法以下:ui
private void updateAlarm(boolean enabled,Alarm alarm); public boolean onContextItemSelected(final MenuItem item); @Override protected void onCreate(Bundle icicle); private void updateLayout(); private void addNewAlarm(); private void onDestory(); public void onCreateContextMenu(ContextMenu menu,View view, ContextMenuInfo menuInfo); public boolean onOptionsItemSelected(MenuItem item); public boolean onCreateOptionsMenu(Menu menu); public void onItemClick(AdapterView parent,View v int pos,long id);
上面的方法不少都咱們比較熟悉的方法吧,呵呵,那就從比較熟悉的方法開始吧。this
(1) 也就是onItemClick()方法,代碼以下:.net
@Override public void onItemClick(AdapterView parent, View v, int pos, long id) { final Cursor c = (Cursor) mAlarmsList.getAdapter() .getItem(pos); final Alarm alarm = new Alarm(c); Intent intent = new Intent(this, SetAlarm.class); intent.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm); startActivity(intent); }
AlarmClock使用一個ListView加+CursorAdapter來顯示全部建立的鬧鐘。
當點擊某一個鬧鐘時,它將進入到鬧鐘的設置界面去:翻譯
上面的代碼的做用很顯然,code
先是所點擊鬧鐘的對應的Cursor對象,而後
經過Alarm類的構造方法,經過Cursor構造了一個Alarm實例。
Alarm類實現了Parcle,咱們能夠暫時將它只想像爲一個實體類,pojo之類的。
後面將詳細分析,或者你如今就去看看唄。呵呵。
而後,new出了Intent,將Alarm類做爲額外數據傳遞過去。上面還出現了Alarms類,
其實你能夠暫時把Alarms類想像爲Java Web開發常常用到的名字dao類,對了你就能夠這樣想Alarms=AlarmDao
呵呵。
而後它就啓動了SetAlarm這個Activity.
好了這個方法的任務完成。
(2)onCreateOptionsMenu()方法
當你按下Menu鍵時,就會調用這個方法,代碼以下;
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.alarm_list_menu, menu); return super.onCreateOptionsMenu(menu); }
代碼很簡單兩行,
第一行:得到菜單構造器,而後經過R.menu.alarm_list_menu菜單資源文件構造菜單。
第二行:子類應用父類的基本實現。
默認實現中將以標準的系統菜單項來填充menu,他們被歸爲CATEGORY_SYSTEM組,因此他們會以應用定義菜單項正確的排列。
(3)onOptionsItemSelected()
代碼以下:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_settings: startActivity(new Intent(this, SettingsActivity.class)); return true; case R.id.menu_item_desk_clock: startActivity(new Intent(this, DeskClock.class)); finish(); return true; case R.id.menu_item_add_alarm: addNewAlarm(); return true; case android.R.id.home: finish(); return true; default: break; } return super.onOptionsItemSelected(item); }
事實在應用中,按下Menu鍵時,只看到了[設置]這一菜單項。看下資源文件以下:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_item_add_alarm" android:title="@string/add_alarm" android:icon="@drawable/ic_menu_add" android:showAsAction="always"/> <item android:id="@+id/menu_item_settings" android:title="@string/settings" android:icon="@android :drawable/ic_menu_preferences" android:showAsAction="never"/> </menu>
注意到android:showAsAction=「always「
因此,這個菜單在ActionBar中顯示了。
注意到 android.R.id.home這個是android4中內置的用於返回的menuItem嗎?須要更多瞭解。
另外重要的一項R.id.menu_item_add_alarm就是添加鬧鐘了。它是做爲ActionBar中的Action一直在顯示。也是咱們將主要關注的。
addNewAlarm();這個方法以下:
private void addNewAlarm() { startActivity(new Intent(this, SetAlarm.class)); }
簡單到不能再簡單了,啓用鬧鐘設置界面。
(4)onCreateContextMenu()
ContextMenu顧名思義就是上下文菜單,在桌面應用中,咱們也許叫作右鍵菜單。在android中通常是
經過長按來觸發的菜單。
@Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { // 從資源文件中上構造菜單Inflate the menu from xml. getMenuInflater().inflate(R.menu.context_menu, menu); // 使用當前項來建立一個自定義view來做爲頭 // Use the current item to create a custom view for the header. final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; // 得到當前項對應Curosr,經過Cursor構造Alarm對象 final Cursor c = (Cursor) mAlarmsList.getAdapter().getItem(info.position); final Alarm alarm = new Alarm(c); // 構造Calendar對象來計算時間 // Construct the Calendar to compute the time. final Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, alarm.hour); cal.set(Calendar.MINUTE, alarm.minutes); // 將時間格式化爲所須要字符串 final String time = Alarms.formatTime(this, cal); // 構造自定義View,併爲每個TextView設置顯示文本 。 // Inflate the custom view and set each TextView's text. final View v = mFactory.inflate(R.layout.context_menu_header, null); TextView textView = (TextView) v.findViewById(R.id.header_time); textView.setText(time); textView = (TextView) v.findViewById(R.id.header_label); textView.setText(alarm.label); // 在菜單中設置自定義頭 // Set the custom view on the menu. menu.setHeaderView(v); //根據鬧鐘狀態,來更改所顯示的文本 // Change the text based on the state of the alarm. if (alarm.enabled) { menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm); } }
代碼比較簡單,並且我也已經在代碼中註釋了,也保留了本來的英文註釋。呵呵,我基本只是翻譯呢。
如今再把context_menu_header的佈局代碼貼在下面,以讓你們加深理解:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="6dip" android:paddingBottom="9dip" android:paddingLeft="10dip" android:paddingRight="10dip"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:paddingTop="6dip" android:paddingRight="10dip" android:src="@drawable/ic_dialog_time"/> <TextView android:id="@+id/header_time" style="?android:attr/textAppearanceLarge" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:gravity="center_vertical" android:ellipsize="none"/> <TextView android:id="@+id/header_label" style="?android:attr/textAppearanceLarge" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="20dip" android:singleLine="true" android:gravity="right|center_vertical" android:ellipsize="end"/> </LinearLayout>
(5)這一個天然就是,onContextItemSelected
代碼以下有點長,可是還算比較清晰吧:
@Override public boolean onContextItemSelected(final MenuItem item) { final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); final int id = (int) info.id; // Error check just in case. if (id == -1) { return super.onContextItemSelected(item); } switch (item.getItemId()) { case R.id.delete_alarm: { // Confirm that the alarm will be deleted. new AlertDialog.Builder(this) .setTitle(getString(R.string.delete_alarm)) .setMessage(getString(R.string.delete_alarm_confirm)) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface d, int w) { Alarms.deleteAlarm(AlarmClock.this, id); } }) .setNegativeButton(android.R.string.cancel, null) .show(); return true; } case R.id.enable_alarm: { final Cursor c = (Cursor) mAlarmsList.getAdapter() .getItem(info.position); final Alarm alarm = new Alarm(c); Alarms.enableAlarm(this, alarm.id, !alarm.enabled); if (!alarm.enabled) { SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes, alarm.daysOfWeek); } return true; } case R.id.edit_alarm: { final Cursor c = (Cursor) mAlarmsList.getAdapter() .getItem(info.position); final Alarm alarm = new Alarm(c); Intent intent = new Intent(this, SetAlarm.class); intent.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm); startActivity(intent); return true; } default: break; } return super.onContextItemSelected(item); }
首先是從菜單項對象中得到AdapterContextMenuInfo類對象實例info
而後經過這個info得到Alarm實例id
而後作了個以防萬一的錯誤檢查。
接着對item的id值作了switch.
狀況1 :用戶選擇了刪除此鬧鐘
彈出一個對話框,讓用戶肯定是否刪除。若是用戶肯定刪除。
調用Alarms.deleteAlarm(context,id)刪除。
狀況2:用戶選擇了啓用/停用鬧鐘
經過info得到position值從而從list的Adpater中得到對應的Cursor對象。
經過Cursor構造Alarm對象。
更新鬧鐘狀態 Alarms.enableAlarm(this,alarm.id,!alarm.enabled)
若是鬧鐘以前是停用狀態,那麼彈出一個Toast,告訴用戶鬧鐘何時會響。
狀況3:用戶選擇了編輯些鬧鐘
構造出鬧鐘對應的Alarm對象。
而後啓動鬧鐘設置界面,並將此Alarm做爲Intent的額外參數傳遞。
到這裏,文章也夠長了,,對於這個類有了一個基本的認識一些普通的代碼分析到這裏。
其它方法的分析仍是另外寫一篇吧。