分享

android | Tatsujin in NCUCC

 venus中醫 2015-10-16

標籤彙整: android

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" />
menu.xml

在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;
}
onOptionsItemSelected.java

我將原本的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;
AlertDialog.java

在前面寫好的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;
Toast.java

一樣是在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;
Notification.java

也是在新增一個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,
就會產生出一個通知了。

Android App教學 第三章 – Layout, Widget, Fragment

本章目標:

照慣例來說說本章目標,
上次使用了兩個Activity完成一個App,
這次要在一個Activity裏使用兩個Fragment,
一個Fragment裏顯示一個清單,
點擊選項之後由另一個Fragment顯示內容,
並且能以返回鍵回到前一個Fragment,
大概是一個這樣的App。

XML:

其實上次的教學已經使用到不少XML了,
比如說strings.xml以及activity_my.xml,
不過上次在設計佈局的時候只使用了Android Studio提供的編輯器,
並沒有直接去編寫XML檔案,
這次會針對這部份,
做更詳細的解釋。

打開上次寫好的activity_my.xml,
這次按Text看看XML的內容,
有寫過HTML的人應該覺得XML的寫法很熟悉,
因為它們都是標籤語言,
整個檔案都是由一堆標籤寫出的元素組成的。

每個元素大致上都是長這個樣子的:
<tag attr="attr">value</tag>
tag 就是這個元素的名字,例如string
attr 屬性的名稱,例如name,後面的引號內是對這個屬性設定的值,例如上次我們設定了height,一個元素可以有多個屬性。
value 是這個元素的內容,例如上次的身高,在設計佈局裡經常會在包覆其他元素。

另外可能還會看見另一種寫法:
<tag attr="attr" />
大部份的Widget都是這種寫法,
因為它們裡面不會再有其他View
所以不需要value。

一般來說不會直接編輯XML,
都會先使用Android Studio提供的編輯器大致設計好之後再編輯屬性,因此接下來介紹幾個常用的屬性。

XML常見通用屬性:

android:id
在Java裡存取這個元素時使用的ID。

android:layout_width (android:layout_height)
寬度(高度),可以設定match_parent、wrap_content或是精確的值,如果直接輸入值就需要單位。
單位請參考 Dimension ,這裏就不詳述。

android:layout_margin
與相鄰的元素或是邊界的距離,需要上面說的單位。
另外還有android:layout_marginLeft、android:layout_marginRight、android:layout_marginTop、android:layout_marginBottom可以設定四個方向的距離。

android:layout_padding
和上面相似,但這是指自己的邊界與內容的距離,一樣需要單位,也有四個方向的設定。

android:layout_weight
在沒有設定高度或寬度的狀況下,會以這個數值自動分配高度及寬度,不過在某些Layout底下禁止使用要注意。

android:layout_gravity
自己的對齊方向,常用的有這幾個:center、left、right、top、bottom。

android:gravity
跟前者類似,但設定的是內容的對齊方向,常用的值與前者相同。

android:background
背景顏色,格式是#AARRGGBB或是#RRGGBB,
也可以用於設定背景圖,格式是@drawble/[resourceId]。

當然除了這些屬性還有一堆屬性沒列出來,
此外還有一些屬性是限定某些元素或是某些元素的子元素使用,
比方說我們上次設定的Hint就是一個例子。

Layout:

因為只有上述的屬性還是難以設計介面,
Android有提供一些Layout以輕鬆排版,
建立這些Layout的方法也是直接拉出來就行了。

FrameLayout
最單純的排版,會將子元素全部疊起來顯示,類似PS的圖層,
簡單來說就是第一個加入的元素在最底層,
下一個加入的元素在前一個之上,
最後加入的元素在最上層顯示,
通常會使用margin和gravity來決定這些元素的位置。

LinearLayout
最常用的排版之一,會將子元素依序排列出來。
自己必須要有android:orientation的屬性,
值可能是horizontal或是vertical,
表示往右排列或往下排列,
子元素過多的情形經常搭配ScrollView或是HorizontalScrollView。

GridLayout
表格狀的排版,子元素需要有兩個屬性,
android:layout_row、android:layout_column來決定放在第幾列第幾行。

RelativeLayout
最常用的排版之一,也是我最喜歡的排版,
專案剛開好時預設就是這個,
不過這卻是個屬性最複雜的一個,
有一大堆屬性在描述元素彼此之間的排版關係,
因為屬性太複雜了這裡不介紹,
基本上用滑鼠拉就行了。

Widget:

接下來到了設計佈局最重要的部分,
前面的Layout是用於擺放Widget,
而Widget就是使用者會看到,會與之互動的東西,
使用者介面基本上就是靠著這些Widgets拼湊出來的。

TextView
顯示android:text裏的文字,
可以使用html的格式,
透過getText與setText在java裡存取文字。

EditText
輸入框,因為繼承了TextView,
存取方式與上者相同。

Button
按鈕,setOnClickListener來設定按下的事件,
其他還有setOnLongClickListener、setOnTouchListener等可以處理不同的事件。

DatePicker
讓使用者選擇日期,
用getYear、getMonth、getDayOfMonth取得輸入。

TimePicker
讓使用者輸入時間(小時和分鐘)。

AnalogClock & DigitalClock
用於顯示時間。

ProgressBar
顯示進度條。

SeekBar
可讓使用者拖動的進度條,
以getProgress取得輸入。

ScrollView
使內容可以垂直捲動。

HorizontalScrollView
使內容可以水平捲動。

常見的Widget大致上就是這些,
之所以沒有詳細的使用說明,
那是因為這次的練習並不會使用到這些,
而且每個Widget的細節都太多了,
基本上需要用到時再立刻查詢如何使用就行了。

不過有個Widget我們會立刻詳細介紹,
它叫做ListView,也是今天的主角之一。

ListView

ListView是用於顯示清單的Widget,
需要顯示多個重複結構的項目時使用,
注意別使用ScrollView包住它,
ListView已經自己做好捲動了。

用Android Studio開一個新專案,
在選擇加入Activity類型的頁面,
選Blank Activity with Fragment,
選擇這個是因為之後要這章後半段會用到Fragment,
在這裡先讓Android Studio處理好。

打開res/layout/fragment_my.xml,
先把Hello World!砍掉,
接著從左邊拉一個ListView出來,
如此便完成建立一個ListView。

打開MyActivity.java,
這次我們要寫Code的地方不是onCreate,
這個檔案底下應該可以看到一個叫做PlaceholderFragment的class,
接下來的程式碼是寫在PlaceholderFragment.onCreateView裡的return前面。

ListView listView = (ListView) rootView.findViewById(R.id.listView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data);
listView.setAdapter(adapter);
ListView.java

ListView要顯示任何東西,
都必須透過Adapter,
因此我們在這裡宣告一個ArrayAdapter<String>。

建構子的三個參數分別是Activity、配置樣式的ID、資料,
因為這裡是在Fragment裡面,所以使用getActivity取得Activity,
android.R.layout.simple_list_item_1是Android裏定義好的常數,
代表一種簡單的List Item的樣式。

後面的data是我自己在Activity宣告成private static的String Array,
還有另一個對應的String Array叫做detail。

data = new String[]{getString(R.string.text_view), getString(R.string.edit_text), getString(R.string.button)};
detail = new String[]{getString(R.string.text_view_detail), getString(R.string.edit_text_detail), getString(R.string.button_detail)};
data&detail.java

還記得我上次提到顯示出來的文字要寫在strings.xml裏對吧,
後面的getString(R.string.[name])就是用於取得事先設定好的string。

最後setAdapter就完成了,
這時執行就能看見ListView了。

接下來根據本章目標,
點選其中一個選項時要打開另一個Fragment,
不過在寫這些之前先讓我們學習如何使用Fragment。

新增Fragment:

你可以把Fragment當作是一個小型的Activity,
而且Fragment有自己的生命週期,
一樣是Google畫的圖:

Fragment最大的優點就是不受限於Activity,
比如說可以在不同的Activity顯示同一個Fragment,
甚至可以在一個Activity顯示多個Fragment,
運用得宜可以避免Code重複性太高。

與上次寫Activity時相同,
要先新增一個Fragment,
新增方法也與Activity雷同,
左邊java上點右鍵,
選擇New -> Fragment -> Fragment (Blank),
這次Fragment就叫做DetailFragment吧,
記得把include interface callbacks取消勾選,
因為我們這次用不到它。

先去編輯自動生成出來的fragment_detail.xml,
將上面原本的TextView刪掉,
新增一個Large Text,用於顯示內容。

回到java,首先看到的是檔案裡有三行TODO,
第一個是要重新命名兩個常數,
剛好這個Fragment會用到標題以及內容兩個參數,
所以將它重新命名為ARG_TITLE以及ARG_DETAIL吧,
在上面按下shift+F6就能重新命名,
使用到這個常數的地方也會自動更新。
第二個及第三個TO-DO也同樣重新命名。

開啟Fragment:

需要在ListView有選項被點選時開啟Fragment,
因此我們先去抓ListView的事件。

listView.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity());
setOnItemClickListener.java

在剛才設定Adapter的下面新增這一行,
上次我們去抓Button的onClick的時候是直接new一個Listener傳進去,
不過我們這次換另一種寫法,
讓MyActivity implements AdapterView.OnItemClickListener,
這個做到好處是可以從MyActivity裡抓到事件而不是OnItemClickListener。

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    DetailFragment detailFragment = DetailFragment.newInstance(data[position], detail[position]);
    fragmentTransaction.replace(R.id.container, detailFragment);
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();
}
OnItemClick.java

在MyActivity中Override這個事件,
因為剛才對ListView設定了Listener,
所以有選項被點選時會呼叫到這裡。

首先以getFragmentManager取得所需的FragmentManager,
呼叫他的beginTransaction得到FragmentTransaction,
接下來設定各個細節,
replace將前者ID的Fragment替換成後者,
addToBackStack這次的Transaction推進BackStack,
如此之後在按返回鍵時,能關閉新Fragment開回舊Fragment,
最後別忘了commit才會生效。

接下來要在Fragment裡面將拿到的title及detail顯示出來,

getActivity().getActionBar().setTitle(title);
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.detail);
textView.setText(detail);
return rootView;
onCreateView.java

這段Code是寫在DetailFragment.onCreateView裡面,
第一行是將title顯示在ActionBar,
inflate是原本就在這個函式裏的Code,
功能是取得fragment_detail.xml,
但是這裡我們將它存進一個叫做rootView的變數,
為了從裡面取得我們事先放好的TextView,
並且設定detail進去。

@Override
public void onPause() {
    super.onPause();
    getActivity().getActionBar().setTitle(R.string.app_name);
}
onPause.java

最後別忘了,
在Fragment被關閉時要將ActionBar上的title還回去。
這時執行App,我們已經做到本章目標的要求了。

關閉Fragment:

雖然已經做到本章目標了,
但有個地方可以再做得更好,
使用Android手機的各位應該都有注意到,
在DetailFragment的畫面時,
左上角應該要變成返回鍵。

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
    setHasOptionsMenu(true);
}
onActivityCreated.java

在DetailFragment Override這個function,
第一行是先前提過的super,
setDisplayHomeAsUpEnabled(true)能使左上角顯示返回鍵,
而setHasOptionsMenu(true)的功能是告訴Fragment我有Menu,
如此一來當左上角被按下去時,
才能從Fragment裡抓到事件。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            getActivity().getFragmentManager().popBackStack();
            return true;
    }
    return super.onOptionsItemSelected(item);
}
onOptionsItemSelected

在DetailFragment Override這個function,
當左上角被點選時會呼叫到這裡,
使用FragmentManager的popBackStack就會關閉最上層的Fragment,
並且開回原先的Fragment。

getActivity().getActionBar().setDisplayHomeAsUpEnabled(false);
onPause.java

最後別忘了在onPause裡加上這行,
將左上角恢服原樣,
不然回去之後依然有返回鍵可是相當怪異的。

成果:

投影片:

Android-3.pptx

Android App教學 第二章 – Activity

本章目標:

跟著這篇文章的教學將會寫出一個計算BMI的小App,
不知道為什麼總覺得這個適合拿來練習Activity。
預計做出兩個Activity,
主要的Activity負責輸入的部分,
另一個顯示結果,
大概是這樣的App。

然後提醒一下,點小圖看大圖。

什麼是Activity:

Activity是App最重要的部分,
一個App會由一個或多個Activity組成
它會提供一個畫面跟使用者互動,
類似電腦上的視窗,
沒有Activity就不會有使用者介面,
所以要寫出UI第一個要學的就是如何使用及管理你的Activities

Activity Lifecycle:

在講解如何寫Activity之前,
必須先理解它的生命週期,
這個Lifecycle提供了一些事件,
使我們能輕鬆管理Activity,
從Google畫的這張圖可以快速理解Lifecycle到底在做什麼。

Lifecycle

 

onCreate是這之中最常使用的,
App打開首先被呼叫到的函式,
介面通常會在這個函式中建立。

onRestart在App重啟時被呼叫。
onStart會在能被使用者看見時被呼叫;
onResume則是當這個Activity到最上層時被呼叫;
onPause離開最上層時;
onStop使用者無法看見時;
onDestroy關閉時。

上面這六個函式在簡單的App中不會用到,
不過這篇教學中會用到onRestart敬請期待,
以後當App寫得更複雜更龐大時,
你會發現這幾個函式非常好用。

目前需要注意的是,
這些函式必須先呼叫super,
以及這些函式不能放花時間的程序,
因為這幾個函式是在打開、切換、關閉App時會被呼叫,
如果太花時間使用者就會感覺到明顯的Lag,
假如真有需要跑這麼久的東西那就另外開Thread吧。

再來就算Activity關閉了,
onStop、onDestroy也有可能不會被呼叫到,
這表示Activity走了圖中左邊的路線,
這時就沒辦法依靠這兩者,
解決辦法會在以後的課程中提到。

這裏舉幾個例子:
打開Activity -> onCreate -> onStart -> onResume
執行時按返回鍵 -> onPause -> onStop -> onDestroy
執行時按最近使用程式鍵 -> onPause -> onStop
最近使用程式時往旁邊滑掉 -> onDestroy
最近使用程式時點回去 -> onRestart -> onStart -> onResume
執行時按home鍵 -> onPause -> onStop

接下來的比較複雜一點,
假設現在有兩個Activity叫做A1及A2,
從A1中開啟A2 -> A1.onPause -> A2.onCreate -> A2.onStart -> A2.onResume -> A1.onStop
再關閉A2 -> A2.onPause -> A1.onRestart -> A1.onStart -> A1.onResume -> A2.onStop -> A2.onDestroy

至於什麼情形會用到這些函式,
比方說你的Activity用到相機,
那你應該在onPause將它關閉;
又比方說你的Activity有動畫,
那就該在onStop時將它停止。

打開上次開好的專案,
java裏MyActivity.java的檔案中,
應該可以看到Android Studio幫你寫好的onCreate,
底下雖然還有其他函式,
它們是用於建立Menu的函式,
但是我們目前用不到。
onCreate裏的第一行就是先前說明的super,
第二行是setContentView,
這個函式的功能是將畫面設定成傳進去的佈局。
接下來讓我們先設計這個佈局再回來寫Code。

簡單佈局設計:

但是在設計佈局之前,
先讓我們準備一下需要顯示的文字,
打開res/values/strings.xml,
裡面已經有一些字串了
照著旁邊的格式新增一些字串吧,
我們預計要做的是計算BMI的App,
那麼我們大致上需要這些字串:
BMI、身高、體重、計算、結果、重設。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">BMI</string>
    <string name="action_settings">Settings</string>
    <string name="height">Height</string>
    <string name="weight">Weight</string>
    <string name="calc">Calc</string>
    <string name="result">Result:</string>
    <string name="reset">Reset</string>
</resources>
strings.xml

這是我設定的字串,
這份Code將app_name設成BMI,
因為在AndroidMenifest.xml裡預設使用這個字串,
BMI會顯示在ActionBar上作為App Name,
我刪掉了hello, world的那一行,
因為我們的App不會再使用到這個字串了。

當然你不一定要設定與我一樣的字串,
但是要注意的是會顯示出來的文字最好寫在這個檔案裡,
這個好習慣之後的維護變得容易,
以後要支援其他語言也會變得相當簡單。

字串的設定完成之後,
打開 layout裏的activity_my.xml,
點選編輯區底下的Design,
會出現一個非常親民的介面,
這裏可以讓你簡單地用圖形化的方式設計layout,
左邊選一下,右邊放一下,就能輕鬆建立出View,
拉出來的View還能用滑鼠移動、縮放,
在上面點兩下可以更改它的ID,
如果是有顯示文字的View也可以同時編輯文字,
這裏的ID能讓java裏存取這個View,
文字請使用剛剛設定好的字串,
按下右邊的三個點就能選擇strings.xml的字串。

神設計www這是我設計的layout,
依序使用了Number (Decimal)、Number (Decimal)、Button,
全部都拉寬。
之所以選用Decimal,
是因為這個才能輸入小數,
普通的Number只能輸入整數,
還有輸入框裏的提示字,
是在右下角的Property設定的,
在其中的Hint選用先前設定的字串。

當然這也不用設計的與我相同,
只要功能都達到就行了。

新增Activity:

主要用於輸入的Acitivity介面已經做好了,
接下來要新增另一個用於顯示結果的Activity,
在左邊的java上按右鍵,
選擇New -> Activity -> Blank Activity,
Activity Name就叫做ResultActivity吧,
按下Finish就成功新增出一個Activity了。

Android Studio會在此同時新增一個layout檔案,
用上面的方法再設計一個layout吧。

神設計2www這張也是我的設計,
依序用到了Large Text、Large Text、Button,
也是一樣拉寬。

這時可以試著執行看看,
剛剛所設計好的精美畫面出現在手機或是模擬器上了,
不過目前還沒有任何功能,
接下來終於要開始寫java了。

開啟Activity – Intent:

需要由java處理的東西是,
在按下計算的時候,
打開ResultActivity,
並且傳身高與體重過去,
計算出結果之後顯示,
還有按下Reset之後關閉且並重設輸入框。

intent是Activity之間溝通的橋樑,
做這些事必然會用到intent,
不過先讓我們取得輸入框中的數字

final EditText height = (EditText) findViewById(R.id.height);
final EditText weight = (EditText) findViewById(R.id.weight);
getEditText.java

這兩行的意思是宣告兩個EditText叫做height和weight,
並且放入後面的東西,
而findViewById這個函式顧名思義就是尋找叫做這個ID的View,
中間的(EditText)是因為findViewById回傳的型別是View,
這裏必需轉型成EditText,
至於前面為什麼會有final,
是因為之後Button的事件裡會使用到。

MyActivity.java的onCreate裡面有一行是setContentView,
setContentView已經依照你寫的layout生出了EditText,
所以在它的後面可以用findViewById得到畫面上的EditText。

接下來寫Button的事件,
按下去時要打開ResultActivity並傳送資料過去。

Button calc = (Button) findViewById(R.id.calc);
calc.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent resultIntent = new Intent(view.getContext(), ResultActivity.class);
        resultIntent.putExtra("height", height.getText().toString());
        resultIntent.putExtra("weight", weight.getText().toString());
        startActivity(resultIntent);
    }
});
buttonEvent.java

這幾行的作用是對叫做calc的Button設定OnClickListener,
那這個Listener裡面宣告了一個Intent叫做resultIntent,
建構子的兩個參數分別是從哪個Activity開啟哪個Activity,
左邊之所以會放view.getContext,
是因為現在是在OnClickListener這個Class裡面,
必須透過參數的view來得到目前執行中的Activity,
而右邊記得要放.class。

putExtra可以傳一些資訊過去,
左邊的字串是用於辨識,
對面的Activity會用左邊的字串來取得右邊的資料,
右邊的資料只要是基本資料型態都能放,
如果想放物件的話會比較麻煩一點,
有興趣的人可以參考這篇:How to send an object from one Android Activity to another using Intents? – Stack Overflow
最後使用startActivity就會透過這個intent開啟Activity了。

intent能做到的是不只有打開同一App裏的其他Activity,
它還能做到呼叫系統App或是打開使用者安裝好的其他App,
我自己就曾經寫過一個App,
它在用到某些功能的時候會呼叫其他App,
如果這個App還沒安裝,
它還會開啟Play商店裏的這個App請使用者安裝,
不過這裡暫時不說明這些用法,
沒意外的話後面的課程會用到的。

另外還有一種常用的函式叫做startActivityForResult,
顧名思義就是需要讓Activity回傳資訊時使用,
需Override一個叫做onActivityResult的函式,
一樣沒意外的話以後會教。

接收Intent:

ResultActivity已經透過intent打開了,
接下來需要在ResultActivity裡接收資訊,
計算之後顯示出結果。

Intent intent = getIntent();
String height = intent.getStringExtra("height");
String weight = intent.getStringExtra("weight");
if (! (height.isEmpty() || weight.isEmpty())) {
    Double heightN = Double.parseDouble(height);
    Double weightN = Double.parseDouble(weight);
    TextView result = (TextView) findViewById(R.id.resultText);
    result.setText(String.valueOf(weightN / (heightN * heightN) * 10000));
}
getIntent.java

要接收intent的方法非常簡單,
只要getIntent就行了,
由於我們剛才是用字串傳過來,
所以這邊使用getStringExtra來取得內容,
如果你傳的是其他型別那就要使用相應的函式。

這裏的if是為了避免傳空的資料進來,
只要有其中一個是空的就不會執行。

將兩個字串轉型成Double,
最後透過result的setText將計算結果顯示出來。

關閉Activity:

ResultActivity最後的任務,
就是按下Reset的時候要將自己關閉。

Button reset = (Button) findViewById(R.id.resetButton);
reset.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        finish();
    }
});
finish.java

關閉比取得intent更簡單,
finish()。

重設輸入框 – onRestart:

回到MyActivity之後,
我們必須要重設輸入框,
畢竟剛剛按了Reset,
這個時候onRestart就派上用場了。

@Override
protected void onRestart() {
    super.onRestart();
    ((EditText) findViewById(R.id.height)).getText().clear();
    ((EditText) findViewById(R.id.weight)).getText().clear();
}
clearEditText.java

成果:

MyActivity
ResultActivity投影片:

Android-2.pptx

 

Android App教學 第一章 – Android Studio, Genymotion, First App

前言:

首先來說說為什麼我要寫這篇教學文吧。
在中央大學有個社團叫NOS,
至於介紹我懶了,自己看吧。
http://nos./wordpress/
總之我可能是這個社團的教學,
然後有點想不開地說想教Android這樣,
於是乎來打打教學文以準備這學期的課。

什麼是Android:

http://zh./wiki/Android
好,講完了。
不過我想各位應該早就知道什麼是Android了,
簡單來說就是一個開源的行動裝置作業系統。

安裝Android Studio:

Android Studio是一個用於寫Android App的整合式開發環境
http://zh./wiki/Android_Studio
到這裡可能會有需多人有疑問,
開發Android不是應該使用Eclipse嗎?
當然你想要使用Eclipse也可以,但是本人偏好使用Android Studio,之後的教學文也會以Android Studio為主。

安裝的第一個步驟當然是先去下載。
https://developer./sdk/installing/studio.html
載完執行安裝檔下一步到最後就安裝完成囉。
安裝完後可能會跳出這樣的畫面:
No JDK
那就代表你還沒安裝Java開發套件,
或是沒有設定到環境變數。
如果是前者就去這裏安裝。
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
選擇你的系統下載並安裝。
如果是後者就照著它的說明設定,
電腦 > 內容 > 進階系統設定 > 環境變數 > 系統變數 > 新增
變數名稱:JAVA_HOME
變數值:C:\Program Files\Java\jdk1.X.0_X(不同的Java版本有不同的X)

成功執行Android Studio之後如果跳出一個視窗詢問是否有舊版Android Studio,按OK就行了。
Android Studio
如果開啟到這個畫面,
那就表示你安裝完Android Studio了。

安裝Genymotion:

Genymotion是目前效能數一數二的Android模擬器,
最重要的是,它是免費的。
http://www.
它的效能好的什麼程度呢?
比我原先使用的HTC Desire V來得快,
因此之前我經常使用這款模擬器。
不過它畢竟只是模擬器,
無法得到Android完整的體驗,
比如藍芽或是多點觸控還做不到,
所以當時偶爾會回到HTC Desire V上開發。
如果你的手機效能超群,
那麼你可以無視這段教學也沒有關係。

安裝一個程式首先必須下載安裝檔,
但是Genymotion必須要有帳號才能下載,
於是乎先來註冊個帳號。
https://cloud./page/customer/login/
將右邊的資料填完,Enterprise size填Personal Usage,Usage type填Development,然後SIGN UP。
Click Here
到信箱收信點箭頭所指的Click here就完成註冊了。

接著到這裡下載Genymotion。
https://cloud./page/launchpad/download/
如果你的電腦裡已經有Virtual Box就下載底下的Other platforms and versions,若否則下載上面的ready-to-run。
接下來照慣例下一步到最後。
Genymotion
如果出現這個畫面那就代表你安裝成功了,
恭喜你可以開始享受Genymotion帶來的體驗了。

新增專案:

那麼終於我們要新增第一個Android Studio的專案,
開啟Android Studio按下New Project,
按照旁邊的說明填上資料,
這裏講幾個比較重要的。
New Project
Application name當然就是這個App的名字,
但這裡必須使用英文,而且首字母需大寫,
如果希望App在手機上顯示中文名稱的話我們之後再做設定。
Company Domain雖說要你填上域名,
但這裡只是用於生成Package name,
基本上隨意就行。
其他的選項目前使用預設。
最後Next幾次之後按下Finish就成功新增專案了,
這裏可能需要跑一段時間請耐心等候。

跑完之後應該會出現這個畫面:
Editor
這裏順便介紹一下介面,
左邊是瀏覽,整個專案底下的資料夾與檔案。
中間是編輯。
右邊是預覽,在開啟Layout或是Drawable之類能夠顯示的東西時會出現。
底下是Log。

開啟GenyMotion虛擬機:

但是在打開虛擬機之前必須要先新增虛擬機,
所以就按下Add,
這時會要求你登入,
使用先前註冊的帳號即可。

接著選擇一個API 19的虛擬機,
一樣Next幾次之後按Finish,
這時會下載虛擬機請耐心等候。
之所以選擇API 19,
是因為目前最新的穩定版本是KitKat。
所以未來Android L的穩定版出來之後,
請選擇API 20。

點兩下剛才新增的虛擬機就能開啟了
GenyMotion

開啟USB偵錯:

在使用自己的手機測試前,
需要打開USB偵錯,
不然電腦沒辦法往裡面安裝APP
設定 > 開發人員選項 > USB偵錯
USB偵錯
但是有些手機沒有開發人員選項
這時需要連續點擊軟體版本號碼才會出現
設定 > 關於 > 軟體資訊 > 版本號碼
版本號碼
設定完USB偵錯記得將手機接上電腦

執行First App:

按下shift+F10或是上面播放形狀的綠色按鍵,
選擇剛剛開啟的虛擬機或是手機,
按下OK。
恭喜你寫出了第一個Android App
First App

投影片:

Android-1.pptx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多