第7章 Fragment片段與選單 7-1 再談Android事件處理 7-2 選項選單與動作列 7-3 內容選單與內容關聯動作模式

Slides:



Advertisements
Similar presentations
從 Android SDK 3.0 開始增加了 2 個新的類別: Fragment 與 Action Bar 。 Fragment 提供不同佈局畫面的另一種用法,但 設計更有彈性,更能針對螢幕大小變化,採用 最合適的設計,例如對較大螢幕的平板裝置, 它可以在一個活動的畫面同時顯示 2 個 Fragment.
Advertisements

第一單元 建立java 程式.
第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
08 CSS 基本語法 8-1 CSS 的演進 8-2 CSS 樣式規則與選擇器 8-3 連結HTML 文件與CSS 樣式表
實驗五:多媒體播放器選單介面.
Part 2 開發Android應用程式的流程
手持式裝置之隨身照護應用 Android開發環境設定 鐘國家 老師.
手持式裝置之隨身照護應用 Android開發環境設定 鐘國家 老師.
Android App 系統開發教學 Luna 陳雯琳 2014/12/18
實驗四:單位轉換程式.
第2章 建立Android應用程式 2-1 Java語言、XML文件與Android 2-2 建立第一個Android應用程式
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
程式設計概論 1.1 程式設計概論 程式語言的演進 物件導向程式 程式開發流程 1.2 C++開發工具
Ch06 再談選單元件 物件導向系統實務.
Q101 在701 SDX Linux上的標準安裝與使用程序v2
Chapter 6 Advanced UI Design.
客戶端的檔案上傳 HtmlInputFile檔案控制項 上傳單一檔案 同時上傳多個檔案.
Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。
Android介面設計 Android智慧型手機程式設計 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2
Android基本程式設計 建國科技大學 資管系 饒瑞佶.
Chapter 6 進階UI設計.
第9章 使用意圖啟動活動與內建應用程式 9-1 意圖的基礎 9-2 使用意圖啟動活動
CH7 佈局、按鈕與文字編輯元件.
Android + Service 建國科技大學 資管系 饒瑞佶.
單元51 在Action Bar上建立Tab標籤頁
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
R教學 安裝RStudio 羅琪老師.
實驗十四:顯示與控制地圖.
第13章 学院介绍 --选项卡切换效果 授课老师:高成珍 QQ号: QQ群: 、
第6章 建立Android使用介面 6-1 介面元件的基礎 6-2 Android的事件處理 6-3 按鈕元件 6-4 文字元件
第8章 對話方塊與資源管理 8-1 對話方塊的基礎 8-2 建立與顯示對話方塊 8-3 使用DialogFragment建立對話方塊
App Inventor2呼叫PHP存取MySQL
CH03 為自己的視窗加上小元件 物件導向系統實務.
Android 專案建立、編譯與執行.
Java 程式設計 講師:FrankLin.
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
SuperGIS 2.0 基本架構介紹.
第一單元 建立java 程式.
實驗十一:待辦事項程式 (儲存在手機上).
主编:钟元生 赵圣鲁.
Ch20. 計算器 (Mac 版本).
第 19 章 XML記憶體執行模式.
Chapter 5 Basic UI Design.
Visual C++ Windows Programming
實驗九:延續實驗八, 製作一個完整音樂播放器
安裝 / 操作 flashget SOP (以Win 7 作業系統為範例)
事件處理 靜宜大學資管系 楊子青.
選單.
GridView.
GridView操作 (II).
第二章 Java语法基础.
螢幕觸控及手勢辨別 靜宜大學資管系 楊子青.
Android視窗介面 建國科技大學 資管系 饒瑞佶 2010/10.
Video 影像 (VideoPlayer 影像播放器、Camcorder 錄影機) 靜宜大學資管系 楊子青
第二章 Java基本语法 讲师:复凡.
進階UI元件:ListView元件以及複選 靜宜大學資管系 楊子青
實驗十:影片播放.
Cloud Training Material- 事件 Sherman Wang
Activity的生命週期: 播放音樂與影片 靜宜大學資管系 楊子青
第2章 Java语言基础.
多國語系 建國科技大學 資管系 饒瑞佶.
String類別 在C語言中提供兩種支援字串的方式 可以使用傳統以null結尾的字元陣列 使用string類別
加速感測器 靜宜大學資管系 楊子青.
NFC (近場通訊, Near Field Communication) 靜宜大學資管系 楊子青
SQLite資料庫 靜宜大學資管系 楊子青.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
Develop and Build Drives by Visual C++ IDE
方法(Method) 函數.
InputStreamReader Console Scanner
Presentation transcript:

第7章 Fragment片段與選單 7-1 再談Android事件處理 7-2 選項選單與動作列 7-3 內容選單與內容關聯動作模式 7-4 彈出式選單 7-5 Fragment片段

7-1 再談Android的事件處理 7-1-1 Android介面元件的事件 7-1-2 長按事件:onLongClickListener 7-1-3 鍵盤事件:onKeyListener 7-1-4 觸控事件:onTouchListener

7-1-1 Android介面元件的事件 – 使用View類別處理介面元件的事件 Android事件處理主要是發生在Activity活動類別的介面元件,我們是透過View類別來處理介面元件產生的事件。 基本上,活動的使用介面是View和ViewGroup物件所組成,在View類別定義有一組巢狀傾聽者介面,提供相關回撥方法(Callback Methods,即介面方法)來幫助我們執行事件處理,例如:觸摸Button元件,OnTouchListener介面的onTouch()方法就會呼叫。 因為Activity類別本身已經實作一些傾聽者介面來處理事件,所以,有些事件我們需要自行建立和註冊傾聽者物件,例如:Click事件;有一些只需覆寫相關回撥方法,例如:KeyDown和KeyUp事件。

7-1-1 Android介面元件的事件 – 事件回撥方法 Android提供相當多事件回撥方法(Event Callback Methods),簡單的說,事件傾聽者就是一組View類別的Java介面,在介面擁有一些回撥方法來處理使用者輸入的相關事件。常用的事件回撥方法,如下表所示: 方法 傾聽者介面 事件來源 onClick() OnClickListener 觸摸螢幕或按下按鍵 onLongClick() OnLongClickListener 觸摸螢幕超過1秒鐘 onKey() OnKeyListener 按下行動裝置的按鍵 onTouch() OnTouchListener 觸摸螢幕 onFocusChange() OnFocusChange 焦點改變 onCreateContextMenu() 長按選單

7-1-2 長按事件:onLongClickListener 長按事件(LongClick Event)是使用者觸摸螢幕且停留超過一秒鐘時觸發,相當於Windows作業系統按下滑鼠右鍵觸發的事件。 基本上,長按事件的事件處理架構和Click事件相同,它是實作OnLongClickListener傾聽者介面的onLongClick()方法,如下所示: public boolean onLongClick(View v) { // 處理LongClick事件的程式碼 return false; }

7-1-3 鍵盤事件:onKeyListener – 說明 鍵盤事件(Keyboard Event)主要是指按下鍵盤按鍵的KeyDown和放開按鍵的KeyUp事件,因為Activity類別實作KeyEvent.Callback介面,所以,我們只需在繼承類別覆寫onKeyDown()和onKeyUp()方法就可以處理這兩種事件。

7-1-3 鍵盤事件:onKeyListener – KeyDown事件 以KeyDown事件的onKeyDown()方法為例,其架構如下所示: public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // 按下的是BACK鍵 return true; } return super.onKeyDown(keyCode, event);

7-1-4 觸控事件:onTouchListener – 說明 Android行動裝置的特點是觸控螢幕,因為Click事件也適用在觸控螢幕,但是Touch事件不能使用在行動裝置的鍵盤,換句話說,對於大部分介面元件來說,建議使用Click事件即可,只有一些特殊觸控操作的手勢(Gestures)才需要使用到Touch事件。

7-1-4 觸控事件:onTouchListener – 動作 觸控事件(Touch Event)主要是在處理手勢的三種動作:ACTION_DOWN、ACTION_MOVE和ACTION_UP(類似滑鼠拖拉過程),如下所示: ACTION_DOWN:手勢動作的開始,可以在手指第1個接觸點的座標建立一個虛擬指標,類似滑鼠游標,只是你看不見。 ACTION_MOVE:當指標在螢幕上移動時就產生此動作(即手指在螢幕上滑動,如同滑鼠游標在螢幕上移動)。 ACTION_UP:手指離開螢幕,可以取得最後1個接觸點指標的座標。

7-1-4 觸控事件:onTouchListener – 判斷動作 在實作的onTouch()方法可以從參數MotionEvent判斷是哪一種動作,如下所示: public boolean onTouch(View v, MotionEvent event) { int act = event.getAction(); switch (act) { case MotionEvent.ACTION_DOWN: // 處理ACTION_DOWN break; case MotionEvent.ACTION_UP: // 處理ACTION_UP case MotionEvent.ACTION_MOVE: // 處理ACTION_MOVE } return false;

7-2 選項選單與動作列 7-2-1 動作列的基礎 7-2-2 建立動作列選單 7-2-3 子選單 7-2-4 選項按鈕選單

7-2 選項選單與動作列 – 種類 選項選單(Options Menu):當使用者按下行動裝置【MENU】鍵,可以在下方顯示選項選單,因為目前裝置大多沒有【MENU】鍵,選項選單已經整合至動作列的overflow選單圖示,稱為溢出選單。 內容選單(Context Menu):即Windows作業系統右鍵快顯功能表,當使用者長按介面元件超過一秒鐘,就會顯示內容選單。 彈出式選單(Popup Menu):我們可以在停泊元件下方顯示類似對話方塊的彈出式選單,如果空間不足,就會顯示在上方。

7-2-1 動作列的基礎 - 認識動作列1 動作列是位在活動上方的一個固定區域,一種介面元件來顯示活動的標題文字、圖示和切換與巡覽功能,也可以用來指示Android應用程式目前所在的活動,和顯示選單(Menu)。

7-2-1 動作列的基礎 - 認識動作列2 Android最常使用的是選項選單(Options Menu),當使用者按下行動裝置的實體【MENU】鍵,可以在下方顯示最多6個選項的選單。不過,目前Android行動裝置大多已經沒有實體【MENU】鍵,選項選單也整合至動作列的overflow選單圖示,對於沒有實體【MENU】鍵的裝置來說,我們需要點選標題列最右方【垂直3點】圖示來開啟選單,如右圖所示:

7-2-1 動作列的基礎 – 選單資源的XML檔案(說明) 選單資源XML檔案的內容是在選單中顯示的選項,我們是使用XML標籤來定義選單的選項,選單資源檔可以使用在第7-2-2節的動作列選單、第7-3節的內容選單和第7-4節的彈出式選單。

7-2-1 動作列的基礎 – 選單資源的XML檔案(新增1) 在Android Studio專案Ch7_2_1的「Project」視窗的【app\res】上,執行【右】鍵快顯功能表的「New/Android resource file」命令新增資源檔,可以看到「New Resource File」對話方塊。

7-2-1 動作列的基礎 – 選單資源的XML檔案(新增2) 開啟menu_main.xml選單資源檔後,從「Palette」視窗拖拉【Menu Item】至活動上方的動作列,可以新增選項,如下圖所示:

7-2-1 動作列的基礎 – 選單資源的XML檔案(新增3) 重複步驟3.新增4個選項後,即可一一指定選項的屬性,請選第1個選項,在【id】欄輸入【left】;【title】欄輸入【上一頁】;【icon】欄點選欄位後按鈕,選【leftarraw.png】圖示檔;【showAsAction】欄勾選【ifRoom】和【withText】後,按【OK】鈕。

7-2-1 動作列的基礎 – 選單資源的XML檔案(範例) <?xml version="1.0" encoding="utf-8"?> <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:title="上一頁" android:id="@+id/left" android:icon="@drawable/leftarrow" app:showAsAction="ifRoom|withText" /> android:id="@+id/right" android:icon="@drawable/rightarrow" <item android:title="轉華氏" android:id="@+id/toF" app:showAsAction="never" /> <item android:title="轉攝氏" android:id="@+id/toC" </menu>

7-2-1 動作列的基礎 – 選單資源的XML檔案(選單圖示) 請使用複製和貼上命令將2個選單圖示檔,從「Ch07」目錄新增至專案,如下圖所示: 如果選項指定icon屬性的圖示檔,例如:leftarrow.png圖示檔的資源索引是R.drawable.leftarrow類別常數,在XML標籤請使用@drawable/leftarrow參考圖示檔。

7-2-1 動作列的基礎 – 將選單資源XML檔案建立成選單 選單資源XML檔案並不會自動成為選單,我們需要在Android Studio執行「Code/Override Methods」命令,在MainActivity類別新增【android.app.Activity】類別下的onCreateOptionsMenu()方法,然後將選單資源建立成選單,如下所示: @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_main, menu); return super.onCreateOptionsMenu(menu); }

7-2-2 建立選項選單 – 說明 在這一節筆者準備在Android應用程式建立位在上方動作列的選項選單,也稱為溢出選單。

7-2-2 建立動作列選單 – 處理動作列選單的選項 我們需要在MainActivity類別覆寫onOptionsItemSelected()方法來判斷使用者的選擇,如下所示: @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.toF: …... break; case R.id.toC: } return super.onOptionsItemSelected(item);

7-2-3 子選單 – 說明 在動作列選單中,每一個選項可以是另一個選單,稱為「子選單」(Sub Menu),不過,子選單並不允許再擁有另一個子選單。例如:Android Studio專案Ch7_2_3的執行結果,如下圖所示:

7-2-3 子選單 – 選單資源的XML檔 在選單資源的XML檔的<item>標籤中,可以看到另一個menu元素,如下所示: <item android:id="@+id/item02" android:title="子選單" app:showAsAction="never"> <menu> <item android:id="@+id/item03" android:title="子項目1"></item> <item android:id="@+id/item04" android:title="子項目2"></item> </menu> </item>

7-2-3 子選單 – onOptionsItemSelected()方法1 public boolean onOptionsItemSelected(MenuItem item) { TextView output = (TextView) findViewById(R.id.lblOutput); switch (item.getItemId()) { case R.id.item01: output.setText("項目1"); return true; case R.id.item02: output.setText("子選單"); case R.id.item03:

7-2-3 子選單 – onOptionsItemSelected()方法2 output.setText("子項目1"); return true; case R.id.item04: output.setText("子項目2"); case R.id.item05: output.setText("項目2"); } return super.onOptionsItemSelected(item);

7-2-4 選項按鈕選單 – 說明 在動作列選單也可以建立成選擇功能的選項按鈕選單,我們可以群組選項來建立成選項按鈕,例如:Android Studio專案Ch7_2_4的執行結果,如下圖所示:

7-2-4 選項按鈕選單 – 選單資源XML檔1 選單資源XML檔是使用<group>標籤來群組選項建立成選項按鈕,如下所示: <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <group android:checkableBehavior="single"> <item android:id="@+id/menu_red" android:orderInCategory="1" app:showAsAction="never" android:title="紅色"/> ......

7-2-4 選項按鈕選單 – 選單資源XML檔2 ...... <item android:id="@+id/menu_green" android:orderInCategory="3" app:showAsAction="never" android:title="綠色"/> </group> </menu>

7-2-4 選項按鈕選單 – onOptionsItemSelected()方法1 在覆寫onOptionsItemSelected()方法是使用android:id屬性值判斷執行功能,不過,我們需要自行處理是否選擇指定選項,如下所示: public boolean onOptionsItemSelected(MenuItem item) { Button btn = (Button) findViewById(R.id.button); switch(item.getItemId()){ case R.id.menu_red: if (item.isChecked()) item.setChecked(false); else item.setChecked(true); btn.setBackgroundColor(Color.RED); return true;

7-2-4 選項按鈕選單 – onOptionsItemSelected()方法2 ...... case R.id.menu_green: if (item.isChecked()) item.setChecked(false); else item.setChecked(true); btn.setBackgroundColor(Color.GREEN); return true; } return super.onOptionsItemSelected(item);

7-3 內容選單與內容關聯動作模式 7-3-1 內容選單 7-3-2 內容關聯動作模式

7-3 內容選單與內容關聯動作模式 內容選單(Context Menu)對比Windows作業系統就是右鍵快顯功能表,當使用者長按介面元件超過一秒鐘,就會顯示內容選單。Android可以有2種方法來建立內容選單,如下所示: 內容選單:類似對話方塊的選單,如果元件支援,當長按介面元件,就會顯示浮動內容選單。 內容關聯動作模式:此模式是系統實作的動作模式(Action Mode),可以在動作列上方顯示內容選單且支援複選,如果是開發Android 3.0以上版本的應用程式,建議使用此模式。

7-3-1 內容選單 - 說明 在Android建立內容選單和之前的選單相似,我們一樣是使用選單資源檔來建立選單的選項。

7-3-1 內容選單 - 建立內容選單1 如同選項選單,我們也是在onCreateContextMenu()方法將選單資源建立成內容選單,如下所示: menu.setHeaderTitle("選擇按鈕的背景色彩"); getMenuInflater().inflate(R.menu.contextmenu, menu); 上述程式碼呼叫setHeaderTitle()方法指定標題文字後,依序使用串流方法呼叫getMenuInflater()和inflate()方法將選單資源R.menu.contextmenu的選項新增至Menu物件。

7-3-1 內容選單 - 建立內容選單2 內容選單處理選取選項的事件處理是覆寫onContextItemSelected()方法,其結構和onOptionsItemSelected()方法相同,筆者就不重複說明。

7-3-1 內容選單 - 註冊內容選單 內容選單因為是附屬在指定的介面元件,我們需要在指定元件註冊內容選單,例如:Button元件或LinearLayout版面配置等,以便長按介面元件可以顯示內容選單,如下所示: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LinearLayout layout = (LinearLayout) findViewById(R.id.linear); registerForContextMenu(layout); }

7-3-2 內容關聯動作模式– 說明 內容關聯動作模式(Contextual Action Mode)是在動作列上方顯示內容選單,而且支援複選,其建立步驟是在實作ActionMode.Callback介面後,呼叫startActionMode()方法來顯示內容選單(匯入android.view.ActionMode套件)。

7-3-2 內容關聯動作模式– 使用匿名內層類別實作ActionMode.Callback介面1 mCallback = new ActionMode.Callback() { @Override public boolean onPrepareActionMode( ActionMode mode, Menu menu) { return false; } public void onDestroyActionMode(ActionMode mode) { mMode = null;

7-3-2 內容關聯動作模式– 使用匿名內層類別實作ActionMode.Callback介面2 @Override public boolean onCreateActionMode( ActionMode mode, Menu menu) { // 建立上下文選單 return true; } public boolean onActionItemClicked( ActionMode mode, MenuItem item) // 處理使用者的選擇 return false; };

7-3-2 內容關聯動作模式– 呼叫startActionMode()方法顯示內容選單 View.OnLongClickListener listener = new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if(mMode!=null) return false; else { mMode = startActionMode(mCallback); v.setSelected(true); } return true; }; btn.setOnLongClickListener(listener);

7-4 彈出式選單 – 說明 彈出式選單(Popup Menu)的顯示方式類似對話方塊,它是指定介面元件建立的專屬選單,例如:按下按鈕,可以在元件下方顯示彈出式選單。請注意!Android需要是API 11以上版本才支援彈出式選單。

7-4 彈出式選單 – 建立 我們是在介面元件的事件處理來建立和顯示彈出式選單,如下所示: PopupMenu popup = new PopupMenu(MainActivity.this, view); popup.setOnMenuItemClickListener(MainActivity.this); popup.inflate(R.menu.popmenu); popup.show(); 上述程式碼使用建構子建立PopupMenu物件,建構子的第1個參數是Context物件,即活動本身,第2個是所屬的介面元件,然後註冊活動本身是OnMenuItemClickListener傾聽者物件,接著使用選單資源建立選單內容,最後呼叫show()方法顯示彈出式選單。

7-4 彈出式選單 – 處理使用者選取的選項 在活動需要實作PopupMenu.OnMenuItemClickListener介面來作為傾聽者物件,我們是在onMenuItemClick()方法處理使用者選取的選項。

7-5 Fragment片段 7-5-1 Fragment片段的基礎 7-5-2 在活動建立Fragment片段

7-5-1 Fragment片段的基礎 – 認識Fragment片段(說明) 在Android活動可以使用Fragment類別來模組化使用介面,方便我們建立適合使用在小螢幕和大螢幕等不同尺寸的Android應用程式。 Fragment片段是一個可重複使用的類別,類別實作活動的部分使用介面和行為,簡單的說,Fragment片段定義部分使用介面,因為是模組化的部分使用介面,同一Fragment片段就可以內嵌在1至多個不同活動,稱為宿主活動(Host Activity),請注意!Fragment片段一定需要內嵌在活動,並不能單獨的獨立執行。 如同活動,每一個Fragment片段包含Java類別和對應的版面配置檔,可以將介面元件和功能封裝起來,方便我們在不同活動來重複使用。

7-5-1 Fragment片段的基礎 – 認識Fragment片段(圖例)

7-5-1 Fragment片段的基礎 – Fragment片段的生命周期

7-5-1 Fragment片段的基礎 – 主要方法的說明 onAttach() 當Fragment片段連接活動時呼叫 onCreate() 初始建立Fragment片段時呼叫 onCreateView() Fragment片段需要建立使用介面時呼叫 onActivityCreated() 當宿主活動完成onCreate()方法時呼叫 onDestroyView() 在刪除Fragment片段後呼叫 onStart() 當Fragment片段可見時呼叫

7-5-2 在活動建立Fragment片段 – 說明 Android Studio工具提供現成範本,可以幫助我們在專案新增Fragment片段,在本節的範例專案分別使用<fragment>標籤和Java程式碼來顯示片段內容。

7-5-2 在活動建立Fragment片段 – 新增片段1 請啟動Android Studio新增名為Ch7_5_2專案後,展開專案套件,在名稱上執行【右】鍵快顯功能表的「New/Fragment/Fragment(Blank)」命令,可以看到新增片段的精靈畫面。

7-5-2 在活動建立Fragment片段 – 新增片段2 請切換至fragment_first.xml檔,新增與修改TextView元件的ID屬性值lblOutput;text屬性值是【第一個Fragment片段】。然後切換至FirstFragment.java,開頭匯入所需套件的程式碼,如下所示: import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; 上述程式碼是匯入支援函數庫android.support.v4.app.Fragment, 。

7-5-2 在活動建立Fragment片段 – 新增片段3 然後是繼承Fragment類別的FirstFragment類別宣告,如下所示: public class FirstFragment extends Fragment { public FirstFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_first, container, false); }

7-5-2 在活動建立Fragment片段 – <fragment>標籤(Step1) 在MainActivity類別的activity_main.xml版面配置是使用<fragment>標籤指定顯示的FirstFragment片段。在Android Studio介面設計工具新增<fragment>標籤和片段的步驟,如下所示: Step 1:請切換至activity_main.xml版面配置,刪除TextView元件。

7-5-2 在活動建立Fragment片段 – <fragment>標籤(Step2) Step 2:在「Palette」工具箱的【Layouts】區段選【<fragment>】,拖拉前方圖示至設計編輯器,可以看到「Classes」對話方塊。

7-5-2 在活動建立Fragment片段 – <fragment>標籤(Step3) Step 3:選【FirstFragment】,按【OK】鈕,可以在指定插入點新增FirstFragment片段,如右圖所示:

7-5-2 在活動建立Fragment片段 – <fragment>標籤(Step4-5) Step 4:在下方點選【fragment_first】超連結,指定片段顯示的版面配置檔後,將<fragment>標籤的【layout:width】屬性改為【match_parent】。 Step 5:請執行Android Studio專案,顯示的訊息字串就是片段內容,如下圖所示:

7-5-2 在活動建立Fragment片段 – 在活動管理Fragment片段(說明) 在活動版面配置使用<fragment>標籤新增Fragment片段是靜態指定方式,這一小節我們準備改用Java程式碼來切換顯示Fragment片段。

7-5-2 在活動建立Fragment片段 – 在活動管理Fragment片段1 請在activity_main.xml版面配置的<fragment>標籤前新增水平的2個按鈕後,在標籤後新增一個FrameLayout版面配置,作為切換Fragment片段的容器元件,如下圖所示:

7-5-2 在活動建立Fragment片段 – 在活動管理Fragment片段2 因為我們準備在FrameLayout切換顯示不同的Fragment片段,請在專案再新增名為SecondFragment片段(版面配置是fragment_second.xml)。現在,我們可以使用程式碼指定FrameLayout這個容器顯示第一個Fragment片段,首先建立FirstFragment物件,如下所示: FirstFragment ff = new FirstFragment(); 上述程式碼使用建構子建立片段後,即可取得FragmentManager物件來管理片段,使用的是和資料庫類似的交易處理,如下所示: FragmentManager fm = getSupportFragmentManager();

7-5-2 在活動建立Fragment片段 – 在活動管理Fragment片段3 程式碼呼叫getSupportFragmentManager()方法(如果沒有使用支援函數庫,請改為getFragmentManager()方法)取得FragmentManager物件後,呼叫beginTransaction()方法開始執行片段管理的交易,如下所示: FragmentTransaction trans = fm.beginTransaction(); trans.add(R.id.frame, ff); trans.commit(); 上述程式碼呼叫add()方法新增片段,第1個參數是容器元件,第2個是顯示的片段物件,最後呼叫commit()方法確認片段管理交易。

7-5-2 在活動建立Fragment片段 – 在活動管理Fragment片段4 因為方法會傳回取得的物件,所以,可以直接使用串連呼叫方法(Method Chaining),如同項鍊的一串珠子來依序呼叫各方法,如下所示: getSupportFragmentManager().beginTransaction() .replace(R.id.frame, sf) .commit(); 上述程式碼呼叫replace()方法取代片段成為第2個參數的Fragment物件sf。如果需要,我們是呼叫remove()方法刪除片段,參數是欲刪除的Fragment物件,如下所示: .remove(sf)

7-5-2 在活動建立Fragment片段 – Fragment物件的newInstance()類別方法1 SecondFragment類別和FirstFragment類別宣告的結構有些不同,因為建立SecondFragment片段物件時,可以傳遞參數來更改TextView元件內容,所以在類別宣告擁有newInstance()類別方法,如下所示: public class SecondFragment extends Fragment { private static final String MESSAGE = "MESSAGE"; private String msg; public static SecondFragment newInstance(String msg) { SecondFragment fragment = new SecondFragment(); Bundle args = new Bundle(); args.putString(MESSAGE, msg); fragment.setArguments(args); return fragment; }

7-5-2 在活動建立Fragment片段 – Fragment物件的newInstance()類別方法2 在之後是預設的空建構子,如下所示: public SecondFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { msg = getArguments().getString(MESSAGE); } 在onCreate()方法使用getArguments()方法取出物件附加的參數,使用getString()方法取出字串參數。

7-5-2 在活動建立Fragment片段 – Fragment物件的newInstance()類別方法3 然後在onCreateView()方法將片段充氣成元件後,即可指定TextView元件顯示的字串,如下所示: @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate( R.layout.fragment_second, container, false); TextView output = (TextView) view.findViewById(R.id.lblOutput); output.setText(msg); return view; }

7-5-2 在活動建立Fragment片段 – Fragment物件的newInstance()類別方法4 回到MainActivity類別,建立SecondFragment片段物件並不是使用建構子,而是呼叫newInstance()類別方法來建立物件和傳遞參數,如下所示: SecondFragment sf; sf = SecondFragment.newInstance("改成第二個Fragment片段"); FirstFragment是單純使用建構子來建立片段物件,如下所示: FirstFragment ff = new FirstFragment();

7-5-3 在活動與Fragment之間交換資料-說明 在活動與Fragment之間交換資料是透過方法呼叫,我們是使用方法參數來傳遞資料。實務上,為了模組化Fragment片段,並不建議在Fragment片段之間直接交換資料,我們需要透過宿主活動來交換資料。 所以,當我們需要在活動的2個Fragment片段之間傳遞資料時,首先是從第1個Fragment片段傳遞資料至宿主活動,然後再從宿主活動傳遞資料至第2個Fragment片段。

7-5-3 在活動與Fragment之間交換資料-範例 將第6-4節Android應用程式的BMI計算機分割成2個片斷,在第1個BMIFragment片段輸入身高和體重,按下按鈕,可以在第2個TextFragment片段顯示計算結果的BMI值,其執行結果如右圖所示:

7-5-3 在活動與Fragment之間交換資料- 從Fragment片段傳遞資料至宿主活動1 本節範例的BMIFragment片段需要傳遞BMI值至MainActivity活動,也就是在BMIFragment類別呼叫宿主活動的方法,透過的是BMIListener介面,所以,在BMIFragment類別宣告之中擁有BMIListener介面宣告,如下所示: public interface BMIListener { public void onButtonClick(double bmi); }

7-5-3 在活動與Fragment之間交換資料- 從Fragment片段傳遞資料至宿主活動2 在MainActivity類別需要實作BMIListener介面和onButtonClick()方法,如下所示: public class MainActivity extends ActionBarActivity implements BMIFragment.BMIListener { ...... public void onButtonClick(double bmi) { } 上述方法參數bmi是準備從片段傳遞給宿主活動的資料。

7-5-3 在活動與Fragment之間交換資料- 從Fragment片段傳遞資料至宿主活動3 在BMIFragment類別的onAttach()方法可以使用BMIListener介面型態取得MainActivity活動物件,如下所示: public void onAttach(Context context) { super.onAttach(context); try { // 取得父活動物件 activityCallback = (BMIListener) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString() + "需實作BMIListener");

7-5-3 在活動與Fragment之間交換資料- 從Fragment片段傳遞資料至宿主活動4 最後,我們在按鈕的事件處理方法呼叫宿主活動的onButtonClick()方法,參數bmi是計算結果的BMI值,如下所示: activityCallback.onButtonClick(bmi); 透過方法呼叫的參數,就可以將BMI值從BMIFragment片段傳遞至MainActivity宿主活動。

7-5-3 在活動與Fragment之間交換資料- 從宿主活動傳遞資料至Fragment片段1 當MainActivity活動取得從BMIFragment傳遞的BMI值後,我們是呼叫TextFragment類別宣告成public的方法,將BMI值從MainActivity活動傳遞至TextFragment片段,如下所示: public void changeBMIValue(double bmi) { output.setText(Double.toString(bmi)); } 上述changeBMIValue()方法是位在TextFragment類別的public方法。

7-5-3 在活動與Fragment之間交換資料- 從宿主活動傳遞資料至Fragment片段2 在MainActivity類別是在實作的onButtonClick()介面方法呼叫此方法,如下所示: public void onButtonClick(double bmi) { FragmentManager fm = getSupportFragmentManager(); TextFragment tf = (TextFragment) fm.findFragmentById(R.id.fragment2); tf.changeBMIValue(bmi); } 上述方法取得FragmentManager物件後,呼叫findFragmentById()方法取得TextFragment物件後,就可以呼叫changeBMIValue()方法顯示BMI值。

7-5-3 在活動與Fragment之間交換資料- 從宿主活動傳遞資料至Fragment片段3 在onButtonClick()方法的參數bmi是從BMIFragment片段傳遞至活動的資料,再透過呼叫changeBMIValue()方法的參數,將資料傳遞至TextFragment片段。

End