特製的片段類別

片段 API 提供其他子類別,這些子類別會封裝應用程式中找到的一些較通用功能。 這些子類別如下:

  • ListFragment – 此片段可用來顯示系結至資料來源的專案清單,例如陣列或游標。

  • DialogFragment – 此片段會當做對話方塊的包裝函式使用。 [片段] 會顯示其 [活動] 頂端的對話方塊。

  • PreferenceFragment – 此片段可用來將喜好設定物件顯示為清單。

The ListFragment

ListFragment在概念和功能 ListActivity 上非常類似 ;它是在片段中裝載 ListView 的包裝函式。 下圖顯示 ListFragment 在平板電腦和手機上執行的 :

平板電腦和手機上 ListFragment 的螢幕擷取畫面

使用 ListAdapter 系結資料

類別 ListFragment 已經提供預設配置,因此不需要覆寫 OnCreateView 以顯示 的內容 ListFragment 。 會 ListView 使用 實作 ListAdapter 系結至資料。 下列範例示範如何使用簡單的字串陣列來完成此作業:

public override void OnActivityCreated(Bundle savedInstanceState)
{
    base.OnActivityCreated(savedInstanceState);
    string[] values = new[] { "Android", "iPhone", "WindowsMobile",
                "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
                "Linux", "OS/2" };
    this.ListAdapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleExpandableListItem1, values);
}

設定 ListAdapter 時,請務必使用 ListFragment.ListAdapter 屬性,而不是 ListView.ListAdapter 屬性。 使用 ListView.ListAdapter 會導致略過重要的初始化程式碼。

回應使用者選取

若要回應使用者選取專案,應用程式必須覆寫 OnListItemClick 方法。 下列範例顯示其中一種可能性:

public override void OnListItemClick(ListView l, View v, int index, long id)
{
    // We can display everything in place with fragments.
    // Have the list highlight this item and show the data.
    ListView.SetItemChecked(index, true);

    // Check what fragment is shown, replace if needed.
    var details = FragmentManager.FindFragmentById<DetailsFragment>(Resource.Id.details);
    if (details == null || details.ShownIndex != index)
    {
        // Make new fragment to show this selection.
        details = DetailsFragment.NewInstance(index);

        // Execute a transaction, replacing any existing
        // fragment with this one inside the frame.
        var ft = FragmentManager.BeginTransaction();
        ft.Replace(Resource.Id.details, details);
        ft.SetTransition(FragmentTransit.FragmentFade);
        ft.Commit();
    }
}

在上述程式碼中,當使用者選取 中的 ListFragment 專案時,主控活動中會顯示新的片段,其中顯示所選取專案的詳細資料。

DialogFragment

DialogFragment是一種片段,用來在 [片段] 內顯示對話方塊物件,該物件將會浮動在使用中視窗的頂端。 它旨在取代從 Android 3.0) 開始 (的受控對話方塊 API。 下列螢幕擷取畫面顯示 的 DialogFragment 範例:

顯示 [新增車輛編輯] 方塊的 DialogFragment 螢幕擷取畫面

可確保 DialogFragment 片段與對話方塊之間的狀態保持一致。 對話物件的所有互動和控制都應該透過 DialogFragment API 進行,而且不會在對話物件上進行直接呼叫。 API DialogFragment 會為每個實例提供用來 Show() 顯示片段的方法。 有兩種方式可以移除片段:

  • 在 實例上 DialogFragment 呼叫 DialogFragment.Dismiss()

  • 顯示另一個 DialogFragment

若要建立 DialogFragment ,類別會繼承自 Android.App.DialogFragment, ,然後覆寫下列兩種方法之一:

  • OnCreateView – 這會建立並傳回檢視。

  • OnCreateDialog – 這會建立自訂對話方塊。 它通常用來顯示 AlertDialog。 覆寫此方法時,不需要覆寫 OnCreateView

簡單對話方塊

下列螢幕擷取畫面顯示具有 和 兩 ButtonTextView 的簡單 DialogFragment 螢幕擷取畫面:

具有 TextView 和兩個按鈕的範例 DialogFragment

會顯示 TextView 使用者在 中 DialogFragment 按一下一個按鈕的次數,同時按一下另一個按鈕將會關閉片段。 的程式碼 DialogFragment 為:

public class MyDialogFragment : DialogFragment
{
    private int _clickCount;
    public override void OnCreate(Bundle savedInstanceState)
    {
        _clickCount = 0;
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState)
        
        var view = inflater.Inflate(Resource.Layout.dialog_fragment_layout, container, false);
        var textView = view.FindViewById<TextView>(Resource.Id.dialog_text_view);
            
        view.FindViewById<Button>(Resource.Id.dialog_button).Click += delegate
            {
                textView.Text = "You clicked the button " + _clickCount++ + " times.";
            };

        // Set up a handler to dismiss this DialogFragment when this button is clicked.
        view.FindViewById<Button>(Resource.Id.dismiss_dialog_button).Click += (sender, args) => Dismiss();
        return view;
        }
    }
}

顯示片段

如同所有片段,會在 DialogFragment 的內容 FragmentTransaction 中顯示 。

Show()上的 DialogFragment 方法會接受 FragmentTransactionstring 作為輸入。 對話方塊將會新增至活動,並 FragmentTransaction 認可。

下列程式碼示範 Activity 可能用來 Show() 顯示 的方法之一 DialogFragment

public void ShowDialog()
{
    var transaction = FragmentManager.BeginTransaction();
    var dialogFragment = new MyDialogFragment();
    dialogFragment.Show(transaction, "dialog_fragment");
}

關閉片段

在 實例 DialogFragment 上呼叫 Dismiss() 會導致片段從活動中移除,並認可該交易。 將會呼叫與片段解構相關的標準片段生命週期方法。

警示對話方塊

而不是覆寫 OnCreateViewDialogFragment 可能會改為覆寫 OnCreateDialog 。 這可讓應用程式建立由 Fragment 管理的 AlertDialog 。 下列程式碼是使用 AlertDialog.Builder 來建立 Dialog 的範例:

public class AlertDialogFragment : DialogFragment
{
    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {
        EventHandler<DialogClickEventArgs> okhandler;
        var builder = new AlertDialog.Builder(Activity)
            .SetMessage("This is my dialog.")
            .SetPositiveButton("Ok", (sender, args) =>
                                         {
                                             // Do something when this button is clicked.
                                         })
            .SetTitle("Custom Dialog");
        return builder.Create();
    }
}

PreferenceFragment

為了協助管理喜好設定,片段 API 會提供 PreferenceFragment 子類別。 PreferenceFragment類似于PreferencesActivity ,它會在 Fragment 中向使用者顯示喜好設定階層。 當使用者與喜好設定互動時,它們會自動儲存至 共用喜好設定。 在 Android 3.0 或更新版本中,使用 PreferenceFragment 來處理應用程式中的喜好設定。 下圖顯示 的 PreferenceFragment 範例:

內嵌、對話方塊和啟動喜好設定的範例喜好設定Fragment

從資源建立喜好設定片段

喜好設定片段可以使用 PreferencesFragment.AddPreferencesFromResource 方法,從 XML 資源檔擴充。 在 Fragment 生命週期中呼叫此方法的邏輯位置會位於 方法中 OnCreate

PreferenceFragment上圖是藉由從 XML 載入資源所建立。 資源檔為:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

  <PreferenceCategory android:title="Inline Preferences">
    <CheckBoxPreference android:key="checkbox_preference"
                        android:title="Checkbox Preference Title"
                        android:summary="Checkbox Preference Summary" />

  </PreferenceCategory>

  <PreferenceCategory android:title="Dialog Based Preferences">

    <EditTextPreference android:key="edittext_preference"
                        android:title="EditText Preference Title"
                        android:summary="EditText Preference Summary"
                        android:dialogTitle="Edit Text Preferrence Dialog Title" />

  </PreferenceCategory>

  <PreferenceCategory android:title="Launch Preferences">

    <!-- This PreferenceScreen tag serves as a screen break (similar to page break
             in word processing). Like for other preference types, we assign a key
             here so it is able to save and restore its instance state. -->
    <PreferenceScreen android:key="screen_preference"
                      android:title="Title Screen Preferences"
                      android:summary="Summary Screen Preferences">

      <!-- You can place more preferences here that will be shown on the next screen. -->

      <CheckBoxPreference android:key="next_screen_checkbox_preference"
                          android:title="Next Screen Toggle Preference Title"
                          android:summary="Next Screen Toggle Preference Summary" />

    </PreferenceScreen>

    <PreferenceScreen android:title="Intent Preference Title"
                      android:summary="Intent Preference Summary">

      <intent android:action="android.intent.action.VIEW"
              android:data="http://www.android.com" />

    </PreferenceScreen>

  </PreferenceCategory>

</PreferenceScreen>

喜好設定片段的程式碼如下所示:

public class PrefFragment : PreferenceFragment
{
    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        AddPreferencesFromResource(Resource.Xml.preferences);
    }
}

查詢活動以建立喜好設定片段

另一種建立 PreferenceFragment 的技術牽涉到查詢活動。 每個活動都可以使用指向 XML 資源檔的 METADATA_KEY_PREFERENCE 屬性。 在 Xamarin.Android 中,這是透過使用 裝飾活動 MetaDataAttribute 來完成,然後指定要使用的資源檔。 類別 PreferenceFragment 提供 AddPreferenceFromIntent 方法,可用來查詢活動來尋找此 XML 資源,並擴充其喜好設定階層。

下列程式碼片段提供此程式的範例,此程式碼片段會用來 AddPreferencesFromIntent 建立 PreferenceFragment

public class MyPreferenceFragment : PreferenceFragment
{
    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        var intent = new Intent(this.Activity, typeof (MyActivityWithPreferences));
        AddPreferencesFromIntent(intent);
    }
}

Android 將會查看 類別 MyActivityWithPreference 。 類別必須以 MetaDataAttribute, 裝飾,如下列程式碼片段所示:

[Activity(Label = "My Activity with Preferences")]
[MetaData(PreferenceManager.MetadataKeyPreferences, Resource = "@xml/preference_from_intent")]
public class MyActivityWithPreferences : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        // This is deliberately blank
    }
}

宣告 MetaDataAttribute 將用來擴充喜好設定階層的 XML 資源檔 PreferenceFragmentMetatDataAttribute如果未提供 ,則會在執行時間擲回例外狀況。 當此程式碼執行時, PreferenceFragment 會顯示為下列螢幕擷取畫面:

顯示 PreferenceFragment 之範例應用程式的螢幕擷取畫面