Android應用程式學習筆記
Adding a fragment without a UI
之前文章都是有關如何增加fragment到activity提供UI,然而,也可以使用fragment為activity提供後台行為,沒有額外的UI。
新增一個沒有UI的fragment,從activity利用add(fragment , String)方法(為fragment提供唯一的字串"Tag",-而不是view ID)增加fragment。這樣就新增了fragment,但是,因為不會牽涉到activity佈局中的View,就不用呼叫onCreateView(),所以你不需要實現此方法。
為fragment提供字串Tag並不限制在沒有UI的fragment-你也可以提供字串Tag給有UI的fragment,但是如果fragment沒有UI,那麼字串Tag是唯一能辨識他們的方式。如果你想從activity取得fragment,你需要利用findFragmentByTag()方法。
星期一, 11月 07, 2011
Fragment (五)
Android應用程式學習筆記
Adding a fragment to an activity
通常,fragment會貢獻一部份使用者介面在寄主activity,有兩種方式你可以將fragment增加到activity佈局上。
Adding a fragment to an activity
通常,fragment會貢獻一部份使用者介面在寄主activity,有兩種方式你可以將fragment增加到activity佈局上。
- Declare the fragment inside the activity's layout file
在此方法中,你可以設定fragment的屬性,以下舉例在activity的layout中增加兩個fragment。<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout>
在<fragment>標籤範圍中的android:name屬性具體指定了在layout中實體化的Fragment類。
當系統建立此activity布局時,它實體化佈局中的每個fragment並且呼叫每個fragment的onCreateView()方法去取得每個fragment的布局,系統將onCreateView()回傳的View直接插入<fragment>標籤的位置。 - Or programmatically add the fragment to an existing ViewGroup
在activity運行的任何時間,你可以增加fragment到你的activity布局,你需要指定fragment該置於哪個ViewGroup。在activity布局處理fragment的相關工作(比如新增、移除或是取代fragment),你必須使用FragmentTransaction,你可以從你的activity取得FragmentTransaction實例,如下。 FragmentManager fragmentManager =
你接著可以利用add()方法增加fragment,指定新增的fragment和插入fragment的View。getFragmentManager()FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();ExampleFragment fragment = new ExampleFragment(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();
第一個傳入add()方法是fragment要置入的ViewGroup,由ID來表示,第二個參數是要置入ViewGroup的fragment。一旦你已在FragmentTransaction做了你的改變就必須呼叫commit()方法。
Fragment (四)
Android應用程式學習筆記
Adding a user interface
Fragment通常做為activity的使用者介面的一部份,且貢獻fragment自己的布局給activity。
要提供布局給fragment,你必須實現onCreateView()方法,當該是fragment繪製它的布局的時候,系統呼叫onCreateView()方法。此方法必須回傳一個View物件,該View物件為fragment布局的根節點。
如果你的fragment是ListFragment的子類,預設從onCreateView()回傳為一個ListView。
從onCreateView()回傳一個布局,你可以透過XML布局資源擴張布局,onCreateView()提供了LayoutInflater物件來幫助你擴張布局。
舉例,以下是一個Fragment的子類,從example_fragment.xml文件取得一個布局。
傳入onCreateView()的參數container是parent ViewGroup(來自activity的布局),你的fragment的布局將被放入ViewGroup中。參數savedInstanceState是一個Bundle物件,如果前一個fragment恢復,提供前一個fragment相關的數據。
inflate()方法有三個參數:
Adding a user interface
Fragment通常做為activity的使用者介面的一部份,且貢獻fragment自己的布局給activity。
要提供布局給fragment,你必須實現onCreateView()方法,當該是fragment繪製它的布局的時候,系統呼叫onCreateView()方法。此方法必須回傳一個View物件,該View物件為fragment布局的根節點。
如果你的fragment是ListFragment的子類,預設從onCreateView()回傳為一個ListView。
從onCreateView()回傳一個布局,你可以透過XML布局資源擴張布局,onCreateView()提供了LayoutInflater物件來幫助你擴張布局。
舉例,以下是一個Fragment的子類,從example_fragment.xml文件取得一個布局。
public static class ExampleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.example_fragment, container, false); } }
傳入onCreateView()的參數container是parent ViewGroup(來自activity的布局),你的fragment的布局將被放入ViewGroup中。參數savedInstanceState是一個Bundle物件,如果前一個fragment恢復,提供前一個fragment相關的數據。
inflate()方法有三個參數:
- 你想擴張的布局的ID。
- ViewGroup成為擴張布局的parent。
- 布林值是要表示擴張的布局是否要在擴張時依附在ViewGroup上(在此例中,布林值為fales是因為系統正準備將擴張的布局插入container中-傳入true將在布局最後建立重複的view group)。
Fragment (三)
Android應用程式學習筆記
Creating a Fragment
建立Fragment,必須建立Fragment的子類,Fragment類有很多和Activity類很像的方法,包括回調方法,比如,onCreate()、onStart()、onPause()和onStop()。事實上,如果你正在將已存在的Android應用程式轉換成使用Fragment,你可能能輕鬆地將程式碼從Activity的回調方法移到fragment對應的回調方法中。
通常,你至少應該執行以下的生命週期方法:
onCreate()
也有一些子類你可以繼承,取代Fragment類:
DialogFragment
Creating a Fragment
建立Fragment,必須建立Fragment的子類,Fragment類有很多和Activity類很像的方法,包括回調方法,比如,onCreate()、onStart()、onPause()和onStop()。事實上,如果你正在將已存在的Android應用程式轉換成使用Fragment,你可能能輕鬆地將程式碼從Activity的回調方法移到fragment對應的回調方法中。
通常,你至少應該執行以下的生命週期方法:
onCreate()
當建立fragment時系統呼叫此方法。在方法中,應該為重要的組件完成初始化的動作。onCreateView()
當輪到fragment繪製自己的使用者介面的時候,系統呼叫此方法。為你的fragment繪製使用者介面,你必須從此方法回傳一個View物件,View物件是你的fragment布局的根結點,如果你的fragment沒有提供使用者介面,你可以回傳null。onPause()
系統呼叫此方法作為用戶離開fragment的第一個提示。此方法通常是承擔任何改變的地方,應該保持超過目前用戶使用期間(因為用戶可能不會再回來)。大部分的應用程式都應該至少為每個fragment實現這三個方法,但是也有許多其他回調方法可以使用來處理不同階段的生命週期。
也有一些子類你可以繼承,取代Fragment類:
DialogFragment
顯示一個浮動對話框,比起使用Activity類中的對話框輔助方法,使用此類建立對話框是一個好選擇。因為你可以將fragment對話框併入由activity管理的fragment的back stack。ListFragment
顯示一列由適配器管理的項目列表,類似ListActivity,它提供許多方法管ListView,比如,onListItemClick()回調方法來處理click事件。PreferenceFragment
類似PrefereneceActivity,顯示Preference物件的階層如列表。
星期五, 11月 04, 2011
實作並觀察Activity生命週期
Android應用程式學習筆記
實作說明: 試著觀察生命週期。我們運行兩個activity,並複寫所有生命週期中的回調方法,通過activity A啟動activity B和activity B啟動activity A觀察兩個activity的生命週期變化。
Activity A(HelloActivityActivity):
實作說明: 試著觀察生命週期。我們運行兩個activity,並複寫所有生命週期中的回調方法,通過activity A啟動activity B和activity B啟動activity A觀察兩個activity的生命週期變化。
Activity A(HelloActivityActivity):
- package test.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class HelloActivityActivity extends Activity {
- /** Called when the activity is first created. */
- private Button mBtn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- //初始化所有成員變數
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("Activity1---onCreate");
- mBtn = (Button)findViewById(R.id.button1);
- }
- public void GoToActivity2(View view){
- Intent intent = new Intent(HelloActivityActivity.this , activity2.class);
- startActivity(intent);
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- //釋放所有資源
- super.onDestroy();
- System.out.println("Activity1---onDestory");
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- //此方法執行後,activity失去用戶焦點,
- super.onPause();
- System.out.println("Activity1---onPause");
- }
- @Override
- protected void onRestart() {
- // TODO Auto-generated method stub
- super.onRestart();
- System.out.println("Activity1---onRestart");
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- //此方法執行後,activity取得用戶焦點,
- super.onResume();
- System.out.println("Activity1---onResume");
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- //此方法執行後,用戶看的見activity,置方法監控影響UI的事件,隨時隨環境變化UI
- super.onStart();
- System.out.println("Activity1---onStart");
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- //此方法執行後,用戶無法看見activity,釋放所有在onStart()所有監控影響UI的方法
- super.onStop();
- System.out.println("Activity1---onStop");
- }
- }
Activity B(activity2):
- package test.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class activity2 extends Activity {
- private Button mBtn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.layout2);
- System.out.println("activity2---onCreate");
- mBtn = (Button)findViewById(R.id.button1);
- }
- public void BackToActivity1(View view){
- Intent intent = new Intent(activity2.this , HelloActivityActivity.class);
- startActivity(intent);
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- System.out.println("activity2---onDestory");
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- System.out.println("activtiy2---onPause");
- }
- @Override
- protected void onRestart() {
- // TODO Auto-generated method stub
- super.onRestart();
- System.out.println("activity2---onRestart");
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- System.out.println("activity2---onResume");
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- super.onStart();
- System.out.println("activity2---onStart");
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- super.onStop();
- System.out.println("activity2---onStop");
- }
- }
實驗一:執行activity A後關閉,觀察生命週期變化。
變化如下圖。
發現一個activity開始運行到出現在屏幕上會經過生命週期為onCreate()->onStart()->onResume(),關閉activity會經過生命週期為onPause()->onStop()->onDestory()。實驗二:執行activity A後,A啟動activity B,B再啟動A,接著按"BACK"直到結束整個activity,觀察生命週期變化。
變化如下圖。
觀察activity A啟動時會經過生命週期onCreate()->onStart()->onResume(),A啟動activity B會經過生命週期就比較複雜,首先要啟動B,A會先onPause(),接著換B要運行了,B會執行onCreate()->onStart()->onResume(),B取得用戶焦點,因此,A執行onStop()。執行到此我們來想想task狀態,task目前總共放有兩個activity,下層是最先執行的A,頂層是從A啟動的B,而從B啟動的A正在執行。現在接著按"BACK"按鈕,觀察A先執行onPause()讓在task頂層的B恢復,B執行onRestart()->onStart()->onResume(),A執行onStop()->onDedtory(),A結束,再按一次"BACK"按鈕,觀察B一樣先執行onPause()讓task中剩下的A恢復,A執行onRestart()->onStart()->onResume(),B執行onStop()->onDestory(),B結束,再按一次"BACK"按鈕,應用程式關閉,A執行onPause()->onStop()->onDestory(),A結束。
星期四, 11月 03, 2011
SQLiteOpenHelper
Android應用程式學習筆記
SQLiteOpenHelper
主要功能用於管理資料庫創建與版本的helper類。
此類實現了onCreate(SQLiteDatabase)、onUpgrate(SQLiteDatabase , int , int ),並可以選擇性地實現onOpen(SQliteDatabase),如果資料庫不存在,回呼onCreate(SQLiteDatabase)方法建立資料庫;如果版本不同或需要更新,回呼onUpgrade(SQLiteDatabase , int , int )方法資料庫升級;如果資料庫存在,回呼onOpen(SQLiteDatabase)打開資料庫。
此類別可以使ContentProvider容易地實現,避免阻塞應用程式開啟時資料庫要長時間更新。
它有兩種建構式:
public SQLiteOpenHelper(Context context , String name , SQLiteDatabase.CursorFactory factory , int version)
此類實現的方法:
public void close()
SQLiteOpenHelper
主要功能用於管理資料庫創建與版本的helper類。
此類實現了onCreate(SQLiteDatabase)、onUpgrate(SQLiteDatabase , int , int ),並可以選擇性地實現onOpen(SQliteDatabase),如果資料庫不存在,回呼onCreate(SQLiteDatabase)方法建立資料庫;如果版本不同或需要更新,回呼onUpgrade(SQLiteDatabase , int , int )方法資料庫升級;如果資料庫存在,回呼onOpen(SQLiteDatabase)打開資料庫。
此類別可以使ContentProvider容易地實現,避免阻塞應用程式開啟時資料庫要長時間更新。
它有兩種建構式:
public SQLiteOpenHelper(Context context , String name , SQLiteDatabase.CursorFactory factory , int version)
建立Helper物件來建立、打開、管理資料庫,此方法回傳很快,資料庫直到呼叫getWritableDatabase()或是getReadableDatabase()才會建立或是打開。
參數: context-使用打開或是建立資料庫;name-資料庫名稱;factory-用來建立cursor物件,null表示為使用預設;version-資料庫版本,通常從1開始。如果版本太舊,呼叫onUpgrade(SQLiteDataBase , int , int )更新資料庫,如果版本太新,呼叫onDwongrade(SQLiteDatabase ,int ,int)更新資料庫。
此類實現的方法:
public void close()
關閉任何開啟的資料庫。public SQLiteDatabase getReadableDatabase()
建立且/或開啟資料庫,回傳唯讀的資料庫。
如getWritableDatabase()方法,此方法可能花較長的時間才會回傳,所以你不應該在應用程式的主執行續中呼叫,應該從ContentProvider.onCreate()。
returns: 回傳一個資料庫物件,直到getWritableDatabase()或是close()呼叫時才變成無效。
throws: 如果無法開啟時丟出SQLiteException例外。public SQLiteReadableDatabase()
建立且/或讀及寫的資料庫,第一次呼叫此方法,資料庫被開啟並且呼叫onCreate(SQLiteDatabase)、onUpgrade(SQLiteDatabase , int , int )方法,選擇性地呼叫onOpen(SQLiteDatabase)方法。
更新資料庫可能要花較長時間,你不應該在應用程式主執行續中呼叫此方法,應該從ContentProvider.onCreate()。
returns: 回傳資料庫物件 ,直到close()方法呼叫時才無效。
throws: 如果無法寫入資料庫,丟出例外SQLiteException。public void onCreate(SQLiteDatabase db)
當資料庫第一次被建立時呼叫此方法,建立資料表的地方。
參數: db資料庫。public void onUpgrade(SQLiteDatabase db , int oldVersion , int newVersion)
資料庫升級時呼叫此方法,應該利用此方法實現摘除資料表、新增資料表或任何升級需要的工作。
星期二, 11月 01, 2011
Fragment (二)
Android應用程式學習筆記
Design Philosophy
Android在Android 3.0介紹fragment,主要在更大的屏幕支援更動態及彈性的使用者介面設計,比如平板電腦,因為平板電腦的屏幕比手持的更大,有更多空間綁定及交換使用者介面組件,像fragment的設計允許你不需要管理複雜的視圖階層樹,藉著切割activity的布局成fragments,你變成可以在activity運行時修改activity的外觀,並且將變動保存在由activity管理的back stack中。
例如,有一個新的應用程式利用一個fragment在左邊顯示文章的列表,其他fragment在右邊顯示文章內容-兩個 fragment肩並肩地出現在同一個activity,且每個fragment都擁有自己一組生命週期回調方法來處理它們用戶輸入自己的事件。因此,取代一個activity用來選擇文章,另一個activtiy顯示文章內容,用戶可以在同一個activtiy中選擇文章及閱讀文章,見圖1。
你應該設計fragment為一個模件且可以在activity組件中重複使用,那是因為每個fragment在自己的生命周期回調方法定義了自己的布局及自己的行為,你可以在多個activity中包含同一fragment,所以你應該涉及能重複使用且避免直接從其他fragment操作fragment,這特別重要,因為模件的fragment允許你在不同大小的屏幕中改變fragment的組合。當你設計應用程式支援平板電腦及手持的裝置,你可以基於可用的屏幕空間中在不同布局配置中重複使用fragment來最佳化用戶使用經驗。例如,當無法將fragment塞入手持裝置屏幕,就必須分割fragment。
Design Philosophy
Android在Android 3.0介紹fragment,主要在更大的屏幕支援更動態及彈性的使用者介面設計,比如平板電腦,因為平板電腦的屏幕比手持的更大,有更多空間綁定及交換使用者介面組件,像fragment的設計允許你不需要管理複雜的視圖階層樹,藉著切割activity的布局成fragments,你變成可以在activity運行時修改activity的外觀,並且將變動保存在由activity管理的back stack中。
例如,有一個新的應用程式利用一個fragment在左邊顯示文章的列表,其他fragment在右邊顯示文章內容-兩個 fragment肩並肩地出現在同一個activity,且每個fragment都擁有自己一組生命週期回調方法來處理它們用戶輸入自己的事件。因此,取代一個activity用來選擇文章,另一個activtiy顯示文章內容,用戶可以在同一個activtiy中選擇文章及閱讀文章,見圖1。
你應該設計fragment為一個模件且可以在activity組件中重複使用,那是因為每個fragment在自己的生命周期回調方法定義了自己的布局及自己的行為,你可以在多個activity中包含同一fragment,所以你應該涉及能重複使用且避免直接從其他fragment操作fragment,這特別重要,因為模件的fragment允許你在不同大小的屏幕中改變fragment的組合。當你設計應用程式支援平板電腦及手持的裝置,你可以基於可用的屏幕空間中在不同布局配置中重複使用fragment來最佳化用戶使用經驗。例如,當無法將fragment塞入手持裝置屏幕,就必須分割fragment。
訂閱:
文章 (Atom)


