Thursday, August 1, 2013

Android Application တစ္ခုကို ဘယ္လို design လုပ္မလဲ

Chapter 3
Application Design
          View သုိ႕မဟုတ္ component ေတြရဲ႕ layout ကို main.xml file မွာ XML format နဲ႕ေရးရတယ္။ Application အတြက္ ဘယ္ component (list, text field, button အစရွိသည္) ေတြလိုအပ္တယ္ဆိုတာသတ္မွတ္ျပီးရင္ ဒီ control ေတြရဲ႕ arrangement (ေနရာခ်ထားမႈ), size, label, font, color အစရွိသည္တို႕ကို main.xml file မွာ ေရးရတယ္။  Application ကိုေရးျပီးတဲ့ေနာက္မွာ programmer က interface ကိုသေဘာမက်ဘူးဆိုရင္ ျပန္ေျပာင္းႏုိင္တယ္။ အဲဒီလိုေျပာင္းေပမယ့္  Java class နဲ႕ method ေတြကိုလိုက္ေျပာင္းစရာမလိုဘူး။ ဥပမာ input field ၂ခုကို ေဘးခ်င္းယွဥ္ထားမလား၊ အထက္ေအာက္ထားမလား ဆုိတာကို main.xml file မွာစိတ္ၾကိဳက္ေျပာင္းႏုိင္တယ္။ ဒီလိုေျပာင္းလိုက္တဲ့အတြက္ Java code ထဲမွာ လုိက္ေျပာင္းေပးစရာမလိုဘူး။
Table 3.1 မွာ XML file ေတြနဲ႕ပတ္သက္တဲ့ rule နဲ႕ syntax ေတြကိုျပထားတယ္။

XML file မွာေရးတဲအခါလုိက္နာရမယ့္ rule ေတြကေတာ့

1.  XML element အားလံုးမွာ opening နဲ႕ closing tag ေတြရွိရမယ္။
2.  XML tag ေတြဟာ case sensitive ျဖစ္တယ္။ စာလံုး အၾကီးအေသးလြဲလို႕မရဘူး။
3.  XML element ေတြကိုမွန္မွန္ကန္ကန္ nested လုပ္ရမယ္။
ဥပမာ
<tag1>
<tag2>
</tag2>
</tag1>
4.  XML document ေတြမွာ root element တစ္ခုရွိရမယ္။ Tag တစ္စံု (<tag1> </tag1>) ဟာ document မွာပါ၀င္တဲ့ element အားလံုးကို ငံုထားရမယ္။ အထက္ပါ ဥပမာမွာ tag1 ဟာ tag2 ဆိုတဲ့ element ကုိငံုထားတယ္။ tag1 ဟာ root element ျဖစ္တယ္။
5.  XML attribute value ေတြကုိ single (‘ ‘) or double quote (“ “) ေတြနဲ႕ quote ရမယ္။

The Screen Layout and the main.xml File
Project တစ္ခုကို create လုပ္လိုက္တာနဲ႕ Eclipse ကေန functional application တစ္ခုကို create လုပ္ေပးတယ္။ Application ရဲ႕ screen configuration ကုိ main.xml file မွာျပဳလုပ္ေပးရတယ္။ ေအာက္က main.xml file ကုိေလ့လာၾကည့္ရေအာင္။
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
</LinearLayout>
Opening tag နဲ႕ closing tag ၾကားမွာ element တစ္ခုရွိတယ္။ XML file ေတြကို အဲဒီ element ေတြနဲ႕ဖြဲ႕စည္းထားတယ္။   Opening tag ဆိုတာ < နဲ႕ > ၾကားမွာ tag name ရွိတယ္။ ဥပမာ <some_element>
Closing tag က opening tag နဲ႕အမည္တူတူဘဲျဖစ္ရမယ္။ ဒါေပမယ့္ tag name ရဲ႕ေရွ႕မွာ / ပါတယ္။ ဥပမာ </some_element>
Tag အားလံုးဟာ match ျဖစ္ရမယ္။ ဆိုလိုတာက opening tag ရွိရင္ closing tag ရွိရမယ္။ ေအာက္ပါပံုစံမ်ိဳးလည္းေရးႏိုင္တယ္။
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
အထက္မွာေရးထားတဲ့နည္းဟာ ေအာက္မွာေရးတဲ့နည္းနဲ႕အဓိပါယ္တူတူဘဲျဖစ္တယ္။
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”>
</TextView>
LinearLayout class ဟာ ViewGroup  class ရဲ႕ subclass တစ္ခုျဖစ္တယ္။ XML file မွာသံုးတဲ့ attribute (ဥပမာ orientation,  layout_width,  and layout_length) ေတြကို Java code နဲ႕လည္းေရးလို႕ရတယ္။ Java code နဲ႕ေရးမယ္ဆိုရင္ LinerLayout class ရဲ႕ method ေတြကိုသံုးျပီးေရးရမယ္။
main.xml file ကုိသံုးျခင္းအားျဖင့္ user interface ကို functionality ကေန သီးသန္႕ခြဲထုတ္ျပီး design လုပ္ႏိုင္တယ္။ User interface ကို Java code လံုး၀မေရးဘဲ main.xml file နဲ႕ဘဲေရးလို႕ရတယ္။
အထက္ပါ main.xml file မွာ အျပင္ဘက္ဆံုးမွာရွိတဲ့  LinearLayout  object  ဟာ application ရဲ႕ screen တစ္ခုလံုးကို ကိုယ္စားျပဳတယ္။ layout_width နဲ႕ layout_height attribute ေတြကို fill_parent လို႕သတ္မွတ္ထားတယ္။ ဒီလိုသတ္မွတ္ထားရင္ LinearLayout ဟာ screen တစ္ခုလံုးစာအျပည့္ေနရာယူမွာျဖစ္တယ္။ Screen ရဲ႕ ေဘးတုိက္ေရာ အထက္ေအာက္ေရာေပါ့။ Orientation  attribute  ကိုေတာ့ Vertical  ထားတယ္။ ဆုိလိုတာက ဒီ layout ထဲကို component ေတြထည့္တဲ့အခါ ေထာင္လုိက္အေနအထားနဲ႕ ထည့္မယ္ဆိုတဲ့သေဘာဘဲ (ဥပမာ ပထမ object ရဲ႕ေအာက္မွာ ဒုတိယ object ကိုထားတာမ်ိဳးေပါ့။ ေဘးခ်င္းယွဥ္မထားဘူး) main.xml file ကိုေအာက္ပါအတုိင္း နည္းနည္းျပင္လုိက္ပါ။
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
</LinearLayout>

ျပီးရင္ Application ကို run ၾကည့္ပါ။ (Application တစ္ခုကို run တဲ့အခါ .java file ကို editor မွာဖြင့္ထားျပီးမွ run ရမယ္ဆိုတာမေမ့ပါနဲ႕)
Figure 3.1 မွာလိုမ်ိဳးျမင္ရမယ္။ Text line ၂လုိင္းဟာ အထက္ေအာက္ vertical orientation အတုိင္းျဖစ္ေနတယ္ဆိုတာေတြ႕ရမယ္။ အဲဒါကေတာ့ main.xml file ရဲ႕ LinerLayout မွာ orientation attribute ကုိ vertical ထားခဲ့လို႕ပါ။


Figure 3.1. Emulator display of two TextView objects.
          ဒီတစ္ခါေတာ့ vertical အစား horizontal လုိ႕ေျပာင္းလိုက္ပါ။ Text line ၂လိုင္းဟာ ခုနလို အထက္ေအာက္ျဖစ္မေနေတာ့ဘဲ ေဘးတုိက္ျဖစ္ေနမယ္လို႕ထင္မွာေပါ့။ ဒါေပမယ့္ ျပန္ၾကည့္လိုက္ပါ။ TextView object ေတြရဲ႕ width ကုိ fill_parent ေတြထားခဲ့တယ္ေနာ္။ fill_parent ဆုိရင္ TextView object ေတြဟာ screen ရဲ႕ အက်ယ္တစ္ခုလံုးကိုေနရာယူမွာပါ။ ဒါေၾကာင့္ ပထမ TextView ေဘးမွာ ဒုတိယ TextView ကေနရာယူလုိ႕မရေတာ့ပါဘူး။ ဒါေၾကာင့္ application ကုိ run ရင္ TextView တစ္ခုသာျမင္ရပါမယ္။ (တစ္ခုေပၚတစ္ခုထပ္ေနလို႕ပါ) ဒါေၾကာင့္ TextView ၂ခုလံုးရဲ႕ layout_width ကုိ wrap_content လို႕ေျပာင္းေပးပါ။
main.xml file ဟာေအာက္ပါအတုိင္းျဖစ္ေနရမယ္။
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
</LinearLayout>
Application ကို run ၾကည္ပါ။ Figure 3.2 အတုိင္းျမင္ရမယ္။ Java code ေရးစရာမလိုဘဲ screen တစ္ခုကိုဘယ္လိုလုပ္ရမယ္ဆိုတာ သိျပီေပါ့။


Figure 3.2. Emulator shows two TextViews, arranged horizontally.

အျခား Layout  class ေတြကေတာ့   AbsoluteLayout, FrameLayout,      TableLayout,   and RelativeLayout တုိ႕ျဖစ္တယ္။
AbsoluteLayout  မွာ component ရဲ႕ x, y coordinate ကိုအတိအက်သတ္မွတ္ရတယ္။  Device အမ်ိဳးမ်ိဳးရွိျပီး screen resolution ကလည္းအမ်ိဳးမ်ိဳးရွိတာဆိုေတာ့ AbsoluteLayout သံုးထားရင္ screen resolution အမ်ိဳးမ်ိဳးအတြက္အဆင္ေျပေအာင္ adjust မလုပ္ႏုိင္ဘူးေပါ့။ AbsoluteLayout ဟာ Device တစ္မ်ိဳးထဲအတြက္ဘဲ ရည္ရြယ္ျပီးေရးတဲ့ application မ်ိဳးအတြက္သာအဆင္ေျပတယ္။
FrameLayout  ကေတာ့ control ေတြကို တစ္ခုေပၚတစ္ခုေနရာခ်ထားေပးတယ္။ ဒီ Layout က graphic ေတြအတြက္အဆင္ေျပတယ္။ main.xml file ကုိေအာက္ပါအတုိင္း ေရးျပီးစမ္းရေအာင္။
<?xml version=”1.0″ encoding=”utf-8″?>
<FrameLayout  xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/hello”/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Text View number two”
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Text View number three”
/>
</FrameLayout>

Application ကုိ run ၾကည့္ပါ။ Text string ၃ခုဟာ တစ္ခုေပၚမွာတစ္ခုဆင့္ျပီးရွိေနလိမ့္မယ္။
RelativeLayout ကေတာ့ control တစ္ခုရဲ႕ position ေပၚမူတည္ျပီး အျခား control တစ္ခုကိုေနရာခ်ေပးတယ္။ main.xml file ကုိေအာက္ပါအတုိင္းေရးျပီး run ၾကည့္ပါ။
<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:id=”@+id/centertext”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/hello”
android:layout_centerHorizontal=”true”
android:layout_centerVertical=”true”
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Text View number two”
android:layout_above=”@id/centertext”
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Text View number three”
android:layout_below=”@id/centertext”
/>
</RelativeLayout>
Second TextView က first TextView ရဲ႕အေပၚမွာရွိျပီး third TextView က first TextView ရဲ႕ေအာက္မွာေရာက္ေနတာေတြ႕မယ္။ First TextView မွာ id attribute ေပးတားတာေတြ႕လား။
android:id=”@+id/centertext”
ဒါဘာေၾကာင့္လိုသလည္း။ အျခား TextView ၂ခုဟာ First TextView ရဲ႕ position ကို refer လုပ္ရတာေၾကာင့္ First TextView ကို identify လုပ္ဘို႕လုိတယ္ေလ။ ဒါေၾကာင့္ id attribute ကုိသံုးရတာ။ Programmer အေနနဲ႕ၾကိဳက္ရာ ID ကုိေရြးႏုိင္တယ္။ ေကာင္းတာကေတာ့ အမည္ခပ္တိုတိုေပးတာေကာင္းတယ္။
TableLayout ကေတာ့ TableLayout ထဲမွာ TableRow ေတြထည့္ရတယ္။ Control (object) ေတြကို TableRow ထဲမွာထည့္ရမယ္။  Layout မွာ row တစ္ခုထဲရွိရင္ column ေတြၾကားမွာ gap (ေနရာလြတ္) မရွိဘူး။ Column index မွာ gap ကုိသတ္မွတ္ေပးထားရင္ေတာင္မွ gap မရွိႏုိင္ဘူး။ ဒါေပမယ့္ row ေတြတစ္ခုထက္ပိုရင္ေတာ့ column index ကုိ skip လုပ္ထားတဲ့ေနရာေတြမွာ gap ေတြျဖစ္သြားမယ္။ Column index  ကို android:layout_column  attribute  မွာ သတ္မွတ္ေပးရတယ္။ (ဥပမာ android:layout_column=”1”)
TableLayout အတြက္စမ္းၾကည့္ရေအာင္ main.xml file ကုိေအာက္ပါအတုိင္းေရးပါ။
<?xml version=”1.0″ encoding=”utf-8″?>
<TableLayout  xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TableRow>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 1″
android:layout_column=”0″
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Column 2″
android:layout_column=”1″
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Column 3″
android:layout_column=”3″
/>
</TableRow>
<TableRow>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 1″
android:layout_column=”0″
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Column 2″
android:layout_column=”2″
/>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Column 3″
android:layout_column=”4″
/>
</TableRow>
</TableLayout>
Application ကုိ run ရင္ Figure 3.3 မွာလိုျမင္ရမယ္။
ဒီမွာ column ၅ခုသံုးထားတယ္။ index က 0 to 4 (0,1,2,3,4) ပါ။


 Figure 3.3. Emulator image showing rows and columns.

Layout manager တစ္ခုကိုအျခား layout manager တစ္ခုေအာက္မွာထားလို႕လည္းရတယ္။ ေအာက္ပါ example မွာၾကည့္ပါ။ Outermost layout က LinearLayout ပါ။ သူ႕ထဲမွာ TableLayout ၂ခုပါတယ္။ TableLayout တစ္ခုစီမွာ row တစ္ခုစီနဲ႕ row ထဲမွာ TextView ေတြထည့္ထားတယ္။
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TableLayout
android:background=”#0000ff”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
>
<TableRow>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 1″
android:layout_column=”0″
/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 2″
android:layout_column=”1″
/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 3″
android:layout_column=”3″
/>
</TableRow>
</TableLayout>
<TableLayout
android:background=”#ff0000″
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”>
<TableRow>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 1″
android:layout_column=”0″
/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 2″
android:layout_column=”2″
/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 3″
android:layout_column=”4″
/>
</TableRow>
</TableLayout>
</LinearLayout>

LinearLayout  ရဲ႕ oritenation attribute က vertical ပါ။ ဒါေၾကာင့္ သူ႕ထဲမွာရွိတဲ့ layout ေတြကို အထက္ေအာက္ (top to bottom) ပံုစံေနရာခ်ေပးတယ္။ Horizontal ဆိုရင္ေတာ့ ေဘးတုိက္ (side by side) ေနရာခ်ထားေပးမွာပါ။
TableLayout ရဲ႕ background attribute ကိုေပးထားေသးတယ္။ Color သတ္မွတ္ေပးထားတာပါ။ (#0000FF) ဆိုတာ အျပာေရာင္ပါ။ (#FF0000) ကေတာ့ အနီေရာင္ပါ။
Color ဆိုတာ component value ၃ခုနဲ႕ျပဳလုပ္ထားတာပါ။ Red, green နဲ႕ blue ဆုိတဲ့ component ေတြပါ။ Component တစ္ခုစီရဲ႕ value ဟာ 0 to 255 ျဖစ္ပါတယ္။ ဒီ value ေတြကို hexadecimal (base-16) နဲ႕သတ္မွတ္ထားပါတယ္။
Hexadecimal  value ေတြနဲ႕သူတို႕ရဲ႕ equivalent ျဖစ္တဲ့ decimal value ေတြကို Table 3.2 မွာျပထားပါတယ္။
Table 3.2   Hexadecimal Values and Their Decimal Equivalents
Hex Value                  Decimal Equivalent
0                                                0
1                                                1
2                                                2
3                                                3
4                                                4
5                                                5
6                                                6
7                                                7
8                                                8
9                                                9
A                                                10
B                                                11
C                                                12
D                                                13
E                                                14
F                                                15
ဥပမာ 255 ရဲ႕ hexadecimal value ဟာ FF (15*16 + 15) ျဖစ္ပါတယ္။
pound (#) သေကၤတေနာက္မွာ hex value ၃စံုရွိတယ္။ တစ္စံုစီဟာ color တစ္ခုစီ (red or green or blue) ကို ကိုယ္စားျပဳတယ္။
ဥပမာ #FF0000 ဆုိရင္ red value က FF or 255 ျဖစ္ျပီး green နဲ႕ blue value ေတြက 0 ျဖစ္တယ္။ ဒါေၾကာင့္ #FF0000 ဆိုရင္ pure red ေပ့ါ။
#000000 ဆုိရင္ အမဲေရာင္ပါ။ #FFFFFF ဆိုရင္ အျဖဴေရာင္။ Red, gree နဲ႕ blue တုိ႕အတြက္ same value ကိုဘဲသံုးမယ္ဆိုရင္ shade of gray ကိုရမယ္။ ဥပမာ #AAAAAA ဆုိရင္ red value ကလည္း AA, green value လည္း AA, blue value လည္း AA ျဖစ္တဲ့အတြက္ shade of gray တစ္ခုျဖစ္မယ္။ Value မ်ားေလေလ shade ဟာ  light ျဖစ္ေလေလျဖစ္မယ္။ Value အမ်ိဳးမိ်ဳးေပါင္းစပ္သံုးျခင္းျဖင့္ color အမ်ိဳးမ်ိဳးရမယ္။ ေအာက္မွာ နမူနာျပထားတယ္။


ဒီေနရာမွာ color ေတြသံုးထားတာက TableLayout က ဘယ္ေနရာမွာဆံုးတယ္။ အျခား Layout ကဘယ္ေနရာမွာစတယ္ဆိုတာျမင္သာေအာင္ အေရာင္နဲ႕ျပခ်င္လုိ႕ပါ။
Android control နဲ႕ layout ေတြမွာ background color ေတြထည့္ႏုိင္တဲ့နည္းေတြမ်ားစြာရွိေသးတယ္။ ဒါကနမူနာျပတာပါ။ အထက္ပါ main.xml file ကုိ run ၾကည့္ပါဦး။ Figure 3.4 မွာကဲ့သို႕ျမင္ရမယ္။
main.xml file မွာ layout_width  နဲ႕  android:layout_height ကိုေသခ်ာဂရုျပဳပါ။ ဒီ ၂ခုကိုေသခ်ာ set လုပ္ဘို႕လိုတယ္။ Component ကို left to right ဆြဲဆန္႕ခ်င္တာဆိုရင္ android:layout_width   ကို fill_parent ထားရမယ္။ မဟုတ္ရင္ေတာ့ wrap_content ထားရမယ္။
Top to bottom အတြက္လည္းဒီလိုဘဲ။ Screen တစ္ခုလံုးကိုေနရာယူခ်င္ရင္ android:layout_height  ကို fill_parent ထားမယ္။ မဟုတ္ရင္ warp_content ထားပါ။


Figure 3.4. Emulator image with table rows of different colors.


Android  application မွာ text ေတြကိုမျဖစ္မေနသံုးၾကရတယ္။ ဥပမာ TextView, EditText, text in list အစရွိသျဖင့္ေပါ့။ ဒါေၾကာင့္ text အေၾကာင္းေလ့လာၾကည့္ရေအာင္။ Text တစ္ခုျဖစ္လာဘုိ႕ဘယ္လို font ေတြသံုးမလဲဆိုတာသတ္မွတ္ရမယ္။
Font object တစ္ခုကိုေအာက္ပါအတုိင္း create လုပ္ႏိုင္တယ္။
Font myfont=new Font(“SansSerif”, Font.BOLD, 32);
ဒီ font ရဲ႕ Ttype name က SansSerif, typestyle က bold, point size က 32 ေပါ့။ Text နဲ႕ပတ္သက္ျပီး သတ္မွတ္ႏုိင္တာေတြက
android:textColor
android:textAppearance
android:textSize
android:typeface
android:textStyle
Text နဲ႕ပတ္သက္တဲ့ specification ေတြကို /res/values folder  ေအာက္က styles.xml ဖုိင္မွာေရးရတယ္။ styles.xml ေအာက္ပါအတုိင္းေရးပါ။
<?xml version=”1.0″ encoding=”utf-8″?>
<resources>
<style name=”shout”>
<item name=”android:textColor”>#ff0000</item>
<item name=”android:textSize”>20pt</item>
<item name=”android:textStyle”>bold</item>
</style>
</resources>
အထက္ပါ code ေတြမွာ name ဆိုတာ main.xml file မွာသံုးမယ့္ attribute ပါ။ ဥပမာ main.xml file မွာ text color ကို အနီေရာင္ (#ff0000) ထားခ်င္တယ္ဆိုပါေတာ့။ အနီေရာင္ကို styles.xml file မွာ textColor လို႕ အမည္ေပးထားပါတယ္။
<item name=”android:textColor”>#ff0000</item>
ဒါေၾကာင့္ main.xml file မွာ အနီေရာင္ကုိသံုးခ်င္ရင္ textColor အမည္နဲ႕ေခၚသံုးရပါတယ္။
အျခား value ေတြအတြက္လည္းဒီအတုိင္းပါဘဲ။ ဥပမာ main.xml file ထဲက Text တစ္ခုအတြက္ ဒီ configuration ေတြကိုသံုးခ်င္တယ္ဆိုရင္ main.xml file ရဲ႕ first  TextView  မွာေအာက္ပါအတုိင္းေရးၾကည့္ပါ။
<TextView
style=”@style/shout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Column 1″
android:layout_column=”0″
/>
Application ကို run ရင္ Figure  3.5 မွာျပထားတဲ့အတုိင္းျဖစ္မယ္။

Figure 3.5. Emulator image showing special effects on first TextView object.

Component IDs
android:id=”@+id/centertext”
+ သေကၤတက ဒီ ID ဟာ user က create လုပ္တဲ့ ID ျဖစ္ေၾကာင္းျပတာပါ။ android:id  attribute ဟာ RelativeLayout မွာအသံုးျပဳဘုိ႕လုိသလို XML layout file က component ေတြကို Java code ကေခၚသံုးတဲ့အခါ ဒီ component ေတြကို identify လုပ္ဘို႕အတြက္လည္း ID ကုိသံုးရပါတယ္။ ဥပမာ Application တစ္ခုမွာ user name ကိုရိုက္ထည့္ဘုိ႕ EditText တစ္ခုရွိတယ္ဆိုပါေတာ့။ Programmer အေနနဲ႕ အဲဒီ EditText ထဲမွာ ရိုက္ထည့္လိုက္တဲ့ name ကုိ extract လုပ္ဘို႕လိုလိမ့္မယ္။
Java code ထဲမွာ EditText အတြက္ ေအာက္ပါအတုိင္းလုပ္ေပးရမယ္။ EditText ရဲ႕ object ကို create လုပ္ျပီး main.xml file ထဲက EditText ကုိ id နဲ႕ေခၚ assign လုပ္ေပးရတယ္။
EditText et=null;
et=(EditText)findViewById(R.id.my_EditText);
ဒါဆိုရင္ main.xml file ထဲမွာ id attribute ကုိဘာေၾကာင့္ေပးရတယ္ဆိုတာသိေလာက္ပါျပီ။

A Few Simple Controls
Button ကုိ click လုိက္ရင္ TextView က text ကို uppercase ေျပာင္းကာ EditText မွာျပမယ့္ application တစ္ခုေရးၾကည့္ရေအာင္။ main.xml file ကိုေအာက္ပါအတုိင္းေရးပါ။ LinearLayout ထဲမွာ TextView, Button နဲ႕ EditText တစ္ခုစီထည့္ထားတယ္။

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:id=”@+id/base”
>
<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”My first android application”
android:id=”@+id/my_TextView”
/>
<Button
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Touch me”
android:id=”@+id/my_Button”
/>
<EditText
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:id=”@+id/my_EditText”
/>
</LinearLayout>
main.xml file မွာလုပ္သမွ်အတြက္ Eclipse က create လုပ္ေပးထားတဲ့ R.java file ကုိၾကည့္ရေအာင္။ id class မွာ မွာ Button, EditText နဲ႕ TextView တို႕ရဲ႕ id ေတြကိုေတြ႕ရမယ္။

/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/

package com.sheusi.DemoApp;

public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int base=0x7f060000;
public static final int my_Button=0x7f060002;
public static final int my_EditText=0x7f060003;
public static final int my_TextView=0x7f060001;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
public static final class style {
public static final int shout=0x7f050000;
}
}
Project တစ္ခုကို create လုပ္လုိက္တာနဲ႕ Eclipse ဟာ main Java file အတြက္ basic framework ကုိ build လုပ္ေပးပါတယ္။ အဲဒါကို src folder ထဲမွာေတြ႕ႏုိင္ပါတယ္။ Project create လုပ္စဥ္က Activity name ေပးခဲ့တာရွိပါတယ္။ အဲဒီအမည္နဲ႕ src folder ထဲမွာရွိေနမွာပါ။ (ဥပမာ Activity name ကုိ Demo လို႕ေပးခဲ့ရင္ src folder ထဲမွာ Demo.java အမည္နဲ႕ရွိေနမွာပါ)
Demo.java file မွာ ေအာက္ပါအတုိင္းေရးပါ။
package com.sheusi.DemoApp;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import android.view.View.OnClickListener;
public class Demo extends Activity implements OnClickListener{
/** Called when the activity is first created. */
Button b=null;
EditText et=null;
TextView tv=null;
@Override
public void onCreate(Bundle savedInstanceState)  {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b=(Button)findViewById(R.id.my_Button);
et=(EditText)findViewById(R.id.my_EditText);
tv=(TextView)findViewById(R.id.my_TextView);
b.setOnClickListener(this);
}
public void onClick(View v){
String temp=tv.getText().toString();
temp=temp.toUpperCase();
et.setText(temp);
}
}
ပထမဆံုး statement က package ပါ။
package com.sheusi.DemoApp;
Project create လုပ္စဥ္က package name ေပးခဲ့တာရွိပါတယ္။ အဲဒီအတုိင္းဒီမွာ ေတြ႕မွာပါ။
ေနာက္ တစ္ေၾကာင္းက import နဲ႕စထားပါတယ္။ Application မွာသံုးမယ့္ class ေတြပါ၀င္တဲ့ package ကုိ import လုပ္တာပါ။ ဒီလို import လုပ္ထားျခင္းျဖင့္ ဒီ package မွာပါ၀င္တဲ့ class တစ္ခုကိုအသံုးျပဳတဲ့အခါ package name တစ္ခုလံုးကိုေရးစရာမလုိေတာ့ဘဲ class name သာေရးစရာလိုပါေတာ့တယ္။
ဥပမာတစ္ခုၾကည့္ရေအာင္။ Button ၂ခုကို declare လုပ္ျပီး assign လုပ္ခ်င္တယ္။ import statement လည္းမသံုးထားဘူးဆိုရင္ Button class ရဲ႕ package name ကိုေအာက္ပါအတုိင္း ကုိအျပည့္အစံုေရးေပးရလိမ့္မယ္။
android.widget.Button b1;
android.widget.Button b2;
b1= new android.widget.Button(“click me”);
b2= new android.widget.Button(“quit”);
Button class ပါ၀င္တဲ့ package ကုိေအာက္ပါအတုိင္း import လုပ္ထားရင္ေတာ့
import android.widget.Button;
package name ကုိအျပည့္အစံုေရးစရာမလုိေတာ့ဘဲ Button class ကုိသာေရးဘုိ႕လိုပါေတာ့တယ္။ ဒါေၾကာင့္ package ကုိ import လုပ္ျပီးသံုးတာပါ။
Button b1;
Button b2;
b1= new Button(“click me”);
b2= new Button(“quit”);
Package တစ္ခုမွာ class ေတြအမ်ားၾကီးပါတာဆိုေတာ့ ကိုယ္သံုးခ်င္တဲ့ class ကိုေရြးျပီး import လုပ္ႏုိင္သလို Package မွာပါတဲ့ class ေတြအားလံုးကို import လုပ္ခ်င္ရင္ေတာ့ * ကုိသံုးရမယ္။
import android.widget.*;
ကုိယ္သံုးခ်င္တဲ့ class က ဘယ္ package မွာပါတယ္ဆိုတာဘယ္လိုသိမလဲ။ ဒါကေတာ့ အေတြ႕အၾကံဳကေနမွတ္သားထားရမယ္။ Internet ကေနရွာၾကည့္လို႕လည္းရတယ္။ import မလုပ္ဘဲသံုးမိတဲ့အခါ eclipse က error ျပျပီး ဘယ္ package ကုိ import လုပ္သင့္တယ္ဆုိတာ suggest လုပ္ပါတယ္။ အဲဒီနည္းနဲ႕လည္းသိႏုိင္ပါတယ္။
ေနာက္တစ္လုိင္းက public class တဲ့။ ျပီးေတာ့ Project create လုပ္စဥ္က ေပးထားတဲ့ Activity name ‘Demo’ ဆိုတာေတြ႕မယ္။
public class Demo extends Activity implements OnClickListener{
Android application ရဲ႕ activity အတြက္ေရးတဲ့ class ေတြဟာ Activity class ရဲ႕ subclass ေတြျဖစ္ပါတယ္။ ဒါေၾကာင့္
Demo extends Activity လို႕ေရးတာပါ။
Eclipse က public class Demo extends Activity { လို႕သာ generate လုပ္ေပးတာပါ။ Application ကုိ cutomize (ကိုယ့္စိတ္ၾကိဳက္) လုပ္ခ်င္လို႕ implements OnClickListener လို႕ထပ္ေရးျပီး OnClickListener class ကုိ implement လုပ္တာပါ။
OnClickListener class ဟာ user interface က action (ဥပမာ button click) ကို listen (check) လုပ္ပါတယ္။ (အခ်ိဳ႕ေသာ object ေတြကသာ click message ကုိပုိ႕ႏိုင္ပါတယ္)
ေအာက္ပါ statement ၃ခုကေတာ့ user interface မွာသံုးမယ့္ Button, EditText နဲ႕ TextView ေတြကို declare လုပ္တာပါ။
Button b=null;
EditText et=null;
TextView tv=null;
TextView က text ေတြကို display လုပ္ႏိုင္တယ္။ ဒါေပမယ့္ edit မလုပ္ႏုိင္ဘူး။ Text ကုိ edit လုပ္ခ်င္ရင္ EditText ကုိသံုးရမယ္။
ဒီတစ္ခါေတာ့ Application ကုိ run (စတင္) တဲ့အခါဘာျဖစ္ေစခ်င္လည္း။ ျဖစ္ေစခ်င္တာကို define လုပ္ရပါေတာ့မယ္။ ဥပမာ screen မွာ user interface layout ကုိထုတ္ျပတာမ်ိဳး၊ variable ေတြထဲကို initial value ေတြ ထည့္ထာမ်ိဳးေပါ့။ ဒီဥပမာမွာေတာ့ ေရွ႕မွာ declare လုပ္ထားတဲ့ control (widget) object ေတြထဲကုိ value ေတြ assign လုပ္တယ္။
b=(Button)findViewById(R.id.my_Button);
et=(EditText)findViewById(R.id.my_EditText);
tv=(TextView)findViewById(R.id.my_TextView);
ျပီးရင္ Button နဲ႕ “listener” code ကိုခ်ိတ္ေပးတယ္။
b.setOnClickListener(this);
ဒါေတြကို onCreate() method မွာေရးရတယ္။
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b=(Button)findViewById(R.id.my_Button);
et=(EditText)findViewById(R.id.my_EditText);
tv=(TextView)findViewById(R.id.my_TextView);
b.setOnClickListener(this);
}
Button ကုိ touch လုပ္လိုက္ရင္ ျဖစ္ေစခ်င္တာကို onClick() method မွာေရးတယ္။
public void onClick(View v){
String temp=tv.getText().toString();
temp=temp.toUpperCase();
et.setText(temp);
}
TextView ရဲ႕ text ကုိ ယူျပီး string ေျပာင္းတယ္။ ျပီးရင္ String ‘temp’ ထဲထည့္တယ္။
String temp=tv.getText().toString();
temp ထဲကဟာကို Uppercase ေျပာင္းျပီး temp ထဲျပန္ထည့္တယ္။
temp=temp.toUpperCase();
temp ထဲက Uppercase ေျပာင္းထားတဲဟာကို EditText et မွာ set လုပ္လိုက္တယ္။
et.setText(temp);
Application ကုိ run ရင္ေအာက္ပါအတုိင္းျဖစ္မယ္။
Figure 3.6. Emulator image of the application designed earlier.
ဒီတစ္ခါ application ကုိပိတ္မယ့္ Button တစ္ခုထပ္တည့္ရေအာင္။  mani.xml file ကိုဖြင့္ျပီး EditText ေအာက္မွာ button တစ္ခုထပ္ထည့္ပါ။ (မူလ button တစ္ခုလည္းရွိေနမယ္ေနာ္) android:text attribute မွာ Quit လုိ႕ေပးပါ။ android:id မွာေတာ့ @+id/quit ထားပါ။
ျပီးရင္ Demo.java မွာ ေအာက္ပါအတုိင္းေရးပါ။
package com.sheusi.DemoApp;
import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import android.view.View.OnClickListener;
public class Demo extends Activity implements OnClickListener{
/** Called when the activity is first created. */
Button b=null;
EditText et=null;
TextView tv=null;
Button quitbutton=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b=(Button)findViewById(R.id.my_Button);
quitbutton=(Button)findViewById(R.id.quit);
et=(EditText)findViewById(R.id.my_EditText);
tv=(TextView)findViewById(R.id.my_TextView);
b.setOnClickListener(this);
quitbutton.setOnClickListener(this);
}
public void onClick(View v){
if(v==b){
String temp=tv.getText().toString();
temp=temp.toUpperCase();
et.setText(temp);
}
if(v==quitbutton){
this.finish();
}
}
}
ဒီ ဖုိင္မွာ ေနာက္ထပ္ button object တစ္ခုကို declare လုပ္ျပီး main.xml file ထဲက quit button ကုိ assign လုပ္တယ္။
Button quitbutton=null;
quitbutton=(Button)findViewById(R.id.quit);
ျပီးရင္ quitbutton မွာ OnClickListener ကို assign လုပ္တယ္။
quitbutton.setOnClickListener(this);
Button ၂ခုလံုးမွာ ဒီ OnClickListener ကုိ assign လုပ္ထားတယ္။ ဒီေတာ့ ဘယ္ button ကုိ click လုပ္လည္းဆိုတာဘယ္လိုသိႏိုင္မလည္း။ onClick() ရဲ႕ parameter ျဖစ္တဲ့ View v ကိုၾကည့္ျပီးသိႏုိင္တယ္။ Button class ဟာ View class ရဲ႕ child class ျဖစ္တာေၾကာင့္ v ဆိုတာ button ေတြကို represent လုပ္ပါတယ္။ ဒါေၾကာင့္ onClick() method သံုးျပီးဘယ္ ဘယ္ button ကုိ click လုပ္တယ္ဆုိတာ ဆံုးျဖတ္တယ္။ v == b ဆုိရင္ button b ကို click လုပ္တာေပါ့။ v == quitbutton ဆိုရင္ေတာ့ quitbutton ကုိ click လုပ္တာေပါ့။ view (button) တစ္ခုကို click လုပ္လုိက္ရင္ onClick(View v) method ကုိ call လုပ္တယ္။ v ဆိုတာ click လုပ္လုိက္တဲ့ item (view) ပါ။
finish( ) method ကေတာ့ activity ကုိ အဆံုးသတ္ေပးတာပါ။ Application ကုိ run ျပီး Quit button ကုိ click လုပ္ၾကည့္ပါ။
ဒီတစ္ခါ EditText control ကုိၾကည့္ရေအာင္။ EditText ထဲမွာ text ရုိက္ထည့္တာကို check လုပ္ဘုိ႕ KeyListener ကိုသံုးရမယ္။ Demo.java file မွာေအာက္ပါအတုိင္းျပင္ေရးပါ။
package com.sheusi.DemoApp;
import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
public class DemoAppActivity extends Activity implements OnClickListener,
OnKeyListener{
/** Called when the activity is first created. */
Button b=null;
EditText et=null;
TextView tv=null;
Button quitbutton=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b=(Button)findViewById(R.id.my_Button);
quitbutton=(Button)findViewById(R.id.quit);
et=(EditText)findViewById(R.id.my_EditText);
tv=(TextView)findViewById(R.id.my_TextView);
b.setOnClickListener(this);
quitbutton.setOnClickListener(this);
et.setOnKeyListener(this);
}
public void onClick(View v){
if(v==b){
String temp=tv.getText().toString();
temp=temp.toUpperCase();
et.setText(temp);
}
if(v==quitbutton){
this.finish();
}
}
public boolean onKey(View v, int keyCode, KeyEvent event){
if(event.getAction()==KeyEvent.ACTION_DOWN){
if(keyCode==KeyEvent.KEYCODE_ENTER){
String temp=et.getText().toString();
temp=temp.toUpperCase();
et.setText(temp);
}
}
return false;
}
}
import android.view.View.OnKeyListener; ဆုိတဲ့ import statement တစ္ခုထပ္တုိးလာတာေတြ႕မယ္။ ဒါက OnKeyListener interface ကို implement လုပ္မွာမုိ႕ပါ။ Interface တစ္ခုကို implement လုပ္ရင္ အဲဒီ interface ထဲက application မွာအသံုးျပဳမယ့္ method ေတြအတြက္ code ကို ေရးရပါတယ္။ (method implementation ေပါ့)
ခုဆိုရင္ OnKeyListener interface ကို implement လုပ္ထားတဲ့အတြက္ သူ႕ရဲ႕ method တစ္ခုျဖစ္တဲ့  onKey( ) method အတြက္ code ကုိေရးရမယ္။ onKey( ) method မွာ parameter ၃ခုပါတယ္။ View object ရယ္၊ key ကုိ represent လုပ္တဲ့ integer value (KeyCode) ရယ္၊ KeyEvent object ရယ္ပါ။ KeyCode ဆိုတာက key တစ္ခုခ်င္းစီအတြက္သတ္မွတ္ေပးထားတဲ့ integer value ပါ။ KeyEvent object မွာ action ၂ခုရွိတယ္။ key ကုိ push လုပ္တဲ့ ACTION_DOWN နဲ႕ key ကုိ release လုပ္တဲ့ ACTION_UP  ဆိုျပီး ၂ခုရွိတယ္။ Character မဟုတ္တဲ့ key ေတြအတြက္ေတာ့ symbolic constant ေတြနဲ႕ သတ္မွတ္ထားပါတယ္။ Table 3.5 မွာၾကည့္ပါ။

ခုလုပ္ေနတဲ့ example မွာ user က ‘Enter’ or ‘Return’ key ကုိ touch လုပ္ရင္ respond တစ္ခုခုလုပ္မွာျဖစ္ပါတယ္။ Enter key ရဲ႕ key code က KEYCODE_ENTER ပါ။ Application ကုိ run လုိက္တဲ့အခ်ိန္မွာ EditText control ထဲကိုရိုက္ထည့္တဲ့ keystroke တစ္ခုခ်င္းစီကုိ ေစာင့္ၾကည့္ပါတယ္။ Action event က ACTION_DOWN ျဖစ္တယ္ဆုိရင္ ဘယ္ Key ကုိႏွိပ္တယ္ဆိုတာသိေအာင္ (keycode) ကုိထပ္စစ္ပါတယ္။ keycode က (enter key) ျဖစ္ေနတယ္ဆိုရင္ ဆက္လုပ္ရမွာကေတာ့ EditText မွာရုိက္ထည့္ထားတဲ့ text ကုိ uppercase ေျပာင္းျပီး EditText မွာျပန္ display လုပ္ပါမယ္။


Creating and Configuring an Android Emulator
Emulator အသစ္လုပ္ခ်င္တာ ဒါမွမဟုတ္လုပ္ျပီးသား emulator ကုိ edit/delete/start လုပ္ခ်င္တာေတြအတြက္ Eclipse>Window>Android SDK and AVD Manager ကိုသြားပါ။ AVD ဆိုတာ Android Virtual Device ပါ။ Figure 3.7 မွာၾကည့္ပါ။


ကိုယ့္ application အတြက္လုိအပ္တဲ့ feature ေတြ support လုပ္ေပးႏုိင္တဲ့ emulator ကုိ create လုပ္ရမယ္။ မဟုတ္ရင္ run တဲ့အခါ အဆင္မေျပျဖစ္မယ္။
Emulator ကို တစ္ခုမက create လုပ္ထားႏုိင္တယ္။ Application ကုိ run ဘုိ႕အတြက္ ဘယ္ emulator သံုးမယ္ဆိုတာကုိေရြးခ်ယ္ရေပးရမယ္။ Tool bar ေပၚက Run ေဘးက drop down arrow ကိုႏွိပ္ရမယ္။ ျပီးရင္ Run Configurations ကိုေရြးပါ။
Figure 3.9 မွာၾကည့္ပါ။

ေနာက္တစ္နည္းက Project>Properties>Run/Debug Settings ကေနသြားလည္းရတယ္။ ကိုယ္ run ခ်င္တဲ့ project ကုိေရြးျပီး ညာဘက္က Edit button ကိုႏွိပ္ပါ။ ဘယ္နည္းသံုးသံုးေနာက္ဆံုးမွာ Figure 3.10 မွာျပထားတဲ့အတုိင္္းရမယ္။


Figure 3.10. Run Configurations panel.

ဒီ screen မွာ Target tab ကိုေရြးျပီး ကိုယ္သံုးခ်င္တဲ့ emulator ကိုေရြးပါ။

Communicating with the Emulator
Run ေနတဲ့ emulator ကိုနည္းလမ္း ၂ခုနဲ႕ communicate လုပ္ႏိုင္တယ္။ တစ္နည္းကေတာ့ Telnet connection ကိုသံုးတာပါ။ Network-type connection ပါ။ Development machine မွာ Telnet/SSH client ရွိဘုိ႕လိုတယ္။ ေနာက္တစ္နည္းကေတာ့ Android Debug Bridge (ADB) ကုိသံုးတာပါ။ adb.exe file ဟာ Software Development Kit (SDK) ထဲမွာပါပါတယ္။ SDK ရဲ႕ platform-tools ဖိုဒါေအာက္မွာရွိပါတယ္။  command window ဖြင့္ျပီး platform-tools ေရာက္ေအာင္ navigate လုပ္ပါ။ ျပီးရင္ adb ကုိ run ပါ။
ဥပမာ

Emulator ကုိ connect လုပ္ဘို႕ၾကိဳးစားတဲ့အခ်ိန္္မွာ emulator ကို run ထားရမယ္။
ADB command အခ်ိဳ႕ကို Table 3.6 မွာျပထားတယ္။ ADB ဟာ emulator သာမက real android device နဲ႕လည္း communicate လုပ္ႏုိင္တယ္။ Device နဲ႕ computer ကို USB cable နဲ႕ခ်ိတ္ဆက္ထားျပီး USB debugging ကုိ on ထားဘုိ႕လိုမယ္။

No comments:

Post a Comment