Chapter 6 Advanced UI Design
Advanced UI Design 本章節將介紹四種選單,分別為圖式選單、條列式選單、下拉式選單和整合式選單。 選單通常會包含一些常用的指令,用選單方式通常可以讓程式看起來較為簡單,不會讓程式畫面看起來有一堆功能或按鈕
List Menu 當程式的內容為功能選項、檔案列表等較適合使用條列的方式來呈現時,我們可以使用條列式選單來實做,例如Android的Market應用程式選單,左圖為Market畫面,右圖為範例:
List Menu First way to write – ListView: public class ListMenuExample extends Activity { // 設定選單要顯示的內容 String[] menuItem = { “選單功能1”, “選單功能2”, “選單功能3” , “選單功能4 ”, “選單功能5 ”}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView myListView = (ListView) findViewById(R.id.ListView01); // 將設定的內容利用Adapter顯示在ListView上 myListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, menuItem)); } 首先要製作一個條例式選單須使用到<ListView>元件,在main.xml當中創建一個id為ListView01的<ListView>;在java程式碼部分,首先先宣告一個ListView元件,並使用findViewById找到id為ListView01的<ListView>,接著用setAdapter將程式的內容文字設定到<ListView>當中
List Menu Second way to write – BaseAdapter and ListActivity: public class ListMenuExample01 extends ListActivity { // 設定選單要顯示的內容 String showData[] = {"選單功能1", "選單功能2", "選單功能3", "選單功能4", "選單功能5"}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setListAdapter(new MyListAdapter(this)); } // 將選單內容以列表形式顯示出來 class MyListAdapter extends BaseAdapter{ LayoutInflater myInflater; public MyListAdapter(Context c){ myInflater = LayoutInflater.from(c); public View getView(int position, View convertView, ViewGroup parent) { // 設定部分略 另一種條列式選單,利用BaseAdapter以及ListActivity來達成一樣的效果 在範例中,自訂一個擴展自BaseAdapter 的MyListAdapter類別,並將原類別的Activity換成ListActivity,而在MyListAdapter最重要的Method是複寫getView(),此Method為產生列表的重要關鍵,至於建立的列表數量則會依照getCount()回傳的數量來決定
List Menu Then add image file to the above-mentioned example of list menu: @Override public View getView(int position, View convertView, ViewGroup parent) { final int index = position; ViewContainer vc = new ViewContainer(); if( convertView == null ){ convertView = myInflater.inflate(R.layout.main, null); vc.textView = (TextView) convertView.findViewById(R.id.dataInfo); vc.imageView = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(vc); } else { vc = (ViewContainer) convertView.getTag(); // 設定TextView的文字 vc.textView.setText(showData[index]); // 設定ImageView的圖示 vc.imageView.setImageBitmap(bm); return convertView; 在範例中自訂一個ViewContainer的Class,裡面宣告兩個物件,一為TextView用來置放文字,另一為ImageView,用來放置圖案,若要更進一步客製化顯示的列表,可將要顯示的元件都置放在此Class中,接著再getView時依照此Class來建立列表
List Menu Results of the example is shown below:
Page Menu 分頁選單如下圖的Tab選單,存放這些Tab則是使用TabHost,此分頁選單為Android內建選單。
Page Menu Every Tab correspond to a LinearLayout. XML is shown below: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- 第一個Tab佈局 --> <LinearLayout android:id="@+id/first_tab_layout" androidrientation="vertical" > <!-- 可自訂元件在此 --> <TextView android:text="撥出來電資訊" android:textSize="40sp" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> </LinearLayout>
Page Menu Every Tab corresponds to a LinearLayout. XML is shown below: <LinearLayout android:id="@+id/second_tab_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" androidrientation="vertical" > <!-- 可自訂元件在此 --> <TextView android:text="接聽來電資訊" android:textSize="40sp" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> </LinearLayout> <!-- 第三個Tab佈局 --> <LinearLayout android:id="@+id/third_tab_layout" androidrientation="vertical"> <TextView android:text="未接來電資訊" </FrameLayout>
Page Menu 每個對應的LinearLayout中則是可放使用者自訂的元件。在主程式部分則是擴展自TabActivity,程式碼如下: public class TabMenuExample extends TabActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 獲取TabActivity的TabHost TabHost th = getTabHost(); LayoutInflater.from(this).inflate(R.layout.main, th.getTabContentView(), true); // 加入第一個Tab並設定tab的名稱以及圖示並指定第一個佈局 th.addTab(th.newTabSpec("tab1") .setIndicator("撥出來電",getResources().getDrawable(android.R.drawable.sym_call_outgoing)) .setContent(R.id.first_tab_layout) ); // 加入第二個Tab並設定tab的名稱以及圖示並指定第二個佈局 th.addTab(th.newTabSpec("tab2") .setIndicator("接聽來電",getResources().getDrawable(android.R.drawable.sym_call_incoming)) .setContent(R.id.second_tab_layout) ); // 加入第三個Tab並設定tab的名稱以及圖示並指定第三個佈局 th.addTab(th.newTabSpec("tab3"). setIndicator("未接來電",getResources().getDrawable(android.R.drawable.sym_call_missed)) .setContent(R.id.third_tab_layout) ); } 程式一開始使用getTabHost() 得到TabActivity的TabHost,接著從LayoutInflater指定R.layout.main為存放TabHost的資源檔。再來使用TabHost的addTab() 來加入不同的Tab分頁,在範例中加入了三個Tab,每個Tab利用setContent()來指定對應到main.xml當中哪一個LinearLayout
Page Menu Results of the example is shown below:
Program Interface Design
Program Interface Design 佈景可將整個應用程式依自己建立的風格(style)來做UI設定,而自訂的style可放置在res/values/style.xml內,而定義這些style必須先定義此為<resources>,在<resources>當中建立自訂的<style>,在每個<style>當中可設定各自的<item>元素,程式碼如下: <?xml version="1.0" encoding="utf-8"?> <resources> <!— MyTheme樣式隱藏視窗的Title --> <style name="MyTheme"> <item name="android:windowNoTitle">true</item> </style> <!— MyTextStyle01將文字大小設定為20sp --> <style name="MyTextStyle01"> <item name="android:textSize">20sp</item> <!— MyTextStyle02將文字大小設定為24sp --> <style name="MyTextStyle02"> <item name="android:textSize">24sp</item> </resources>
Program Interface Design From the codes we can see we set 3 <style>, they are : MyTheme, MyTextStyle01 and MyTestStyle02. In MyTheme, there is an <item> named “android:windowNoTitle.” If the attribute is set to true, the program title on the top of the program can be cancelled as below:
Program Interface Design Except for MyTheme, font size of the two Style-MyTextStyle01 and MyTestStyle02-are set to 20sp and 24sp, respectively, as shown below:
Program Interface Design Example of codes is shown below: <?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"> <!— 將TextView01的樣式設定為MyTextStyle01 --> <TextView style="@style/MyTextStyle01" android:text="第一種Style" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <!— 將TextView02的樣式設定為MyTextStyle02 --> style="@style/MyTextStyle02" android:text="第二種Style" android:id="@+id/TextView02" </LinearLayout></resources>
Program Interface Design To apply the style to the entire application, it can be achieved by modifying res/AndroidManifest.xml as shown below: In addition to apply the style to the entire application, it can also apply various style to various components, e.g. main.xml. Here we define two <TextView> and insert the following attribute in TextView: <application … android:theme="@style/MyTheme"> <TextView … style="@style/MyTextStyle01" … >
Program Interface Design The most widely applied <item> in <style>. For more detailed <item>, please refer to /docs/reference/android/R.styleable.html: Item Name Description of Function android:windowNoTitle If it is set to true, there will be no title on the top of the program android:windowTitleSize Set title size of the application android:windowTitleBackgroundStyle Set title background style android:textColor Text color android:textSize Font size android:textStyle Text style:bold, italic and bold italic android:windowBackground Set background of the application android:windowFullscreen Set fullscreen of the application android:layout_width Set width of layout android:layout_height Set height of layout
Q&A