Android App教學 第四章 – Menu, Dialog, Toast, Notification
Menu:
Menu是一個在Android App中相當常用到的要素之一,
各位Android的使用者應該經常在App的右上角看到三個點,
按下去之後會跑出一個選單,
就是Menu。
設計Menu:
Menu與Layout及String一樣,
可以先用xml設計,
程式再以xml的內容生出Menu,
因此寫Menu的第一步就是編輯XML。
以第一章的步驟開好專案後,
首先開啟res/menu/my.xml,
可以看到Android Studio在開啟專案的時候,
已經幫你建立不少東西了,
照著相同的格式寫新的Item就能新增Menu裡的選項。
這裡介紹一些常用的屬性:
android:id
與layout時一樣,用於在java裡存取時用的id
android:title
顯示的文字
android:icon
顯示出來的圖像,值通常是@drable/
android:showAsAction
常用的值有
ifRoom,選項會以圖像顯示在ActionBar上
Never,以文字顯示在Menu裡
<item android:id="@+id/action_change_text"
android:title="@string/action_change_text" />
在res/menu/my.xml裡將原本的item刪掉
並新增這個Item,
這裡的@string/action_change_text是我事先在res/values/strings.xml寫好的字串,其值是Change Text,
執行之後就能看到Menu裡的Setting變成Change Text了,
但是目前點下去沒有任何功能。
接收點選MenuItem的事件:
打開MyActivity.java,
裡面有個函式叫做onCreateOptionsMenu,
Menu會在這個函式中被建立出來,
其中第一行的inflate就是將xml的內容建立出來。
還有一個函式叫做onOptionsItemSelected的函式,
只要Menu有選項被點選就會呼叫這個函式,
參數的MenuItem就是被點到的選項,
可以透過getItemId分辨是何者被點選。
這個函式還有個需要注意的地方,
就是它的回傳值,
如果這個MenuItem是我們要的,
那就必須在處理完事件之後回傳true,
若是這個MenuItem不是我們需要的,
一定要回傳super。
switch (id) {
case R.id.action_change_text:
TextView textView = (TextView) findViewById(R.id.text_view);
textView.setText(R.string.changed);
return true;
}
我將原本的if改寫為switch,
因為當以後MenuItem增加時,
switch會較易閱讀及撰寫。
當R.id.action_change_text被點選時,
會去將R.id.text_view顯示的字設為R.string.changed,
這裡的text_view是我給預設的Hello world!設定的Id,
R.string.changed則是我在res/values/strings.xml所寫的字串,
其值是Changed。
執行之後點選Change Text,
如果看到原先的Hello world!變成Changed,
就表示已經成功抓到事件,
已經學會寫Menu了。
AlertDialog:
各位Android的使用者應該也會覺得這個相當熟悉,
AlertDialog就是會在中間跳出來的小視窗,
可能上面會有一個標題,中間有些說明,底下有是或否的選項。
case R.id.action_open_dialog:
AlertDialog.Builder dBuilder = new AlertDialog.Builder(this);
dBuilder.setTitle("Title");
dBuilder.setPositiveButton("Positive Button", null);
dBuilder.setNegativeButton("Negative Button", null);
dBuilder.setNeutralButton("Neutral Button", null);
dBuilder.setMessage("Message");
dBuilder.show();
return true;
在前面寫好的switch裡多加入這個case,
R.id.action_open_dialog是我在res/menu/my.xml新增的item,
請先去寫這個item。
要建立AlertDialog必須透過AlertDialog.Builder,
建構子的參數是目前執行中的Activity,
因為這段code在MyActivity裡面,
所以使用this就行了。
建立出Builder之後開始設定各個資訊,
setTitle,設定標題;
setPositiveButton,右邊的按鈕,第二個參數是OnClickListener,因為目前沒有要接按下去的事件,所以使用null;
setNegativeButton,左邊的按鈕,第二個參數一樣是OnClickListener;
setNeutralButton,中間的按鈕,一樣有OnClickListener;
setMessage,設定中央的訊息。
設定完之後使用show就能叫出AlertDialog。
上面這些如果有幾項沒有設定,
那就不會顯示那幾樣東西,
比如沒有setTitle,那就不會有標題,
沒有setNeutralButton,那底下就只剩下兩個Button。
注意當底下的三個按鈕被使用者按下時,
或是使用者按了AlertDialog外面,
這個AlertDialog會被關閉。
另外,show會回傳一個AlertDialog,
顯示出來之後還是能透過這個去更改上面的資訊,
也能使用其中的dismiss直接關閉。
執行之後按下Open Dialog,
如果看到中間顯示出一個小視窗,
那就是成功了。
AlertDialog還有個比較進階的用法,
中央並不是只能顯示字串,
還可以使用以下這幾種方法來顯示一個List:
setItems(items, OnClickListener)
以items這個字串陣列顯示一個List。
setMultiChoiceItems(items, checkedItems, OnClickListener)
一樣顯示List,但是這是多選的列表,旁邊會有Checkbox,
checkItems是和items一樣長度的boolean陣列,用於設定事先選好的items,不預先選的話用null。
setSingleChoiceItems(items, checkedItem, OnClickListener)
也是List,但這次是單選,旁邊會有RadioButton,
checkItem是預先選好的編號,如不事先選則用-1。
還有一種用法是直接設定要顯示的View。
setView(view)
Toast:
一樣是Android裡相當常見的東西,
但是這裡光說Toast可能想像不到這是哪個東西,
有時候在畫面中央偏下方會出現一串提示字,
這個東西就是Toast。
case R.id.action_show_toast:
Toast.makeText(this, "This is a toast.", Toast.LENGTH_SHORT).show();
return true;
一樣是在switch新增一個case,
別忘記去menu新增一個選項。
Toast的使用相當簡單,
使用Toast.makeText就能輕鬆建立,
第一個參數是Activity,一樣使用this,
中間是要顯示的文字,
後面是顯示時間,通常是Toast.LENGTH_SHORT或是Toast.LENTH_LONG。
Notification:
身為Android的使用者應該對這個東西再熟悉不過了。
case R.id.action_notify:
Notification.Builder nBuilder = new Notification.Builder(this);
nBuilder.setSmallIcon(R.drawable.ic_launcher);
nBuilder.setContentTitle("Notification Test");
nBuilder.setContentText("This is a notification.");
nBuilder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
nBuilder.setAutoCancel(true);
Intent nIntent = new Intent(this, MyActivity.class);
nIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, nIntent, PendingIntent.FLAG_UPDATE_CURRENT);
nBuilder.setContentIntent(pendingIntent);
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nManager.notify(0, nBuilder.build());
return true;
也是在新增一個case以及一個item。
比起前面的Toast,
Notification複雜多了。
與AlertDialog一樣需要Builder,
建構子的參數依然是Activity所以用this,
底下解釋各個函式的意義:
setSmallIcon,設定顯示的圖案;
setContentTitle,通知的標題;
setContentText,通知的內文;
setDefaults,使用預設設定,這裡用了預設音效及預設震動;
setAutoCancel(true),在通知被點擊時會自動關閉。
接下來宣告以前教過的Intent,
因為要設定使用者點選通知時要開啟這個App,
所以必然會使用到Intent,
setFlags設定一些參數,
這裏使用的兩個參數使它清除原本的Activity並重新開啟一個新的。
PendingIntent用於包裝Intent,
因為這裡的Intent並不是直接使用而是傳給Notification,
所以要以PendingIntent包裝成Notification接受的格式,
使用PendingIntent.getActivity建立,
四個參數分別為Activity、requestCode、Intent、Flags,
requestCode使用0就可以了,這裏用不到。
Flags使用PendingIntent.FLAG_UPDATE_CURRENT,
其他的Flag比較沒有意義。
使用setContentIntent將PendingIntent設定進去之後,
可以讓通知顯示出來了,
先使用getSystemService(NOTIFICATION_SERVICE)取得NotificationManager,
再呼叫它的notify就能產生通知,
兩個參數分別是Id及Notification,
Id以後用於存取Notification,
因為我們不需要更新這個Notification所以使用0,
後面因為它還是Builder,
所以呼叫build讓他生成用於傳入的Notification。
執行之後按下Menu中的Notify,
就會產生出一個通知了。