带片段的 ViewPagerViewPager with Fragments

ViewPager 是一个布局管理器,可用于实现 gestural 导航。Gestural 导航允许用户向左和向右轻扫以逐步浏览数据页。本指南说明如何使用 ViewPager 实现 swipeable UI,并使用片段作为数据页。ViewPager is a layout manager that lets you implement gestural navigation. Gestural navigation allows the user to swipe left and right to step through pages of data. This guide explains how to implement a swipeable UI with ViewPager, using Fragments as the data pages.

概述Overview

ViewPager 通常与片段结合使用,以便更轻松地管理 ViewPager中每个页面的生命周期。ViewPager is often used in conjunction with fragments so that it is easier to manage the lifecycle of each page in the ViewPager. 在本演练中,ViewPager 用于创建一个名为FlashCardPager的应用,用于在闪存卡上提供一系列数学问题。In this walkthrough, ViewPager is used to create an app called FlashCardPager that presents a series of math problems on flash cards. 每个闪存卡都作为一个片段实现。Each flash card is implemented as a fragment. 用户通过闪存卡左右 swipes,点击数学问题以显示其答案。The user swipes left and right through the flash cards and taps on a math problem to reveal its answer. 此应用将为每个闪存卡创建一个 Fragment 实例,并实现从 FragmentPagerAdapter派生的适配器。This app creates a Fragment instance for each flash card and implements an adapter derived from FragmentPagerAdapter. Viewpager 和 Views中,大部分工作都是在 MainActivity 生命周期方法中完成的。In Viewpager and Views, most of the work was done in MainActivity lifecycle methods. FlashCardPager中,大部分工作都是通过其生命周期方法之一 Fragment 来完成的。In FlashCardPager, most of the work will be done by a Fragment in one of its lifecycle methods.

本指南不涵盖片段的基础知识 – 如果你还不熟悉 Xamarin 中的片段,请参阅片段,以帮助你开始处理片段。This guide does not cover the basics of fragments – if you are not yet familiar with fragments in Xamarin.Android, see Fragments to help you get started with fragments.

启动应用项目Start an App Project

创建名为FlashCardPager的新 Android 项目。Create a new Android project called FlashCardPager. 接下来,启动 NuGet 包管理器(有关安装 NuGet 包的详细信息,请参阅演练:在项目中包括 NuGet)。Next, launch the NuGet Package Manager (for more information about installing NuGet packages, see Walkthrough: Including a NuGet in your project). 查找并安装Viewpager 和 Views中所述的Xamarin包。Find and install the Xamarin.Android.Support.v4 package as explained in Viewpager and Views.

添加示例数据源Add an Example Data Source

FlashCardPager中,数据源是由 FlashCardDeck 类表示的一组闪存卡;此数据源提供包含项内容的 ViewPagerIn FlashCardPager, the data source is a deck of flash cards represented by the FlashCardDeck class; this data source supplies the ViewPager with item content. FlashCardDeck 包含数学问题和答案的现成集合。FlashCardDeck contains a ready-made collection of math problems and answers. FlashCardDeck 构造函数不需要任何参数:The FlashCardDeck constructor requires no arguments:

FlashCardDeck flashCards = new FlashCardDeck();

FlashCardDeck 中的闪存卡集合被组织,以便索引器可以访问每个闪存卡。The collection of flash cards in FlashCardDeck is organized such that each flash card can be accessed by an indexer. 例如,下面的代码行检索第四个闪存卡问题:For example, the following line of code retrieves the fourth flash card problem in the deck:

string problem = flashCardDeck[3].Problem;

下面这行代码检索上一个问题的相应答案:This line of code retrieves the corresponding answer to the previous problem:

string answer = flashCardDeck[3].Answer;

由于 FlashCardDeck 的实现细节与理解 ViewPager无关,FlashCardDeck 代码未在此处列出。Because the implementation details of FlashCardDeck are not relevant to understanding ViewPager, the FlashCardDeck code is not listed here. FlashCardDeck.cs上提供了要 FlashCardDeck 的源代码。The source code to FlashCardDeck is available at FlashCardDeck.cs. 下载此源文件(或将代码复制并粘贴到新的FlashCardDeck.cs文件中),并将其添加到项目。Download this source file (or copy and paste the code into a new FlashCardDeck.cs file) and add it to your project.

创建 ViewPager 布局Create a ViewPager Layout

打开Resources/layout/main.axml ,并将其内容替换为以下 XML:Open Resources/layout/Main.axml and replace its contents with the following XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    </android.support.v4.view.ViewPager>

此 XML 定义占用整个屏幕的 ViewPagerThis XML defines a ViewPager that occupies the entire screen. 请注意,必须使用完全限定的名称ViewPager ,因为 ViewPager 打包在支持库中。Note that you must use the fully-qualified name android.support.v4.view.ViewPager because ViewPager is packaged in a support library. ViewPager 仅适用于Android 支持库 v4;它在 Android SDK 中不可用。ViewPager is available only from the Android Support Library v4; it is not available in the Android SDK.

设置 ViewPagerSet up ViewPager

编辑MainActivity.cs并添加以下 using 语句:Edit MainActivity.cs and add the following using statements:

using Android.Support.V4.View;
using Android.Support.V4.App;

更改 MainActivity 类声明,使其派生自 FragmentActivityChange the MainActivity class declaration so that it is derived from FragmentActivity:

public class MainActivity : FragmentActivity

MainActivity 派生自FragmentActivity (而不是 Activity),因为 FragmentActivity 知道如何管理对片段的支持。MainActivity is derived fromFragmentActivity (rather than Activity) because FragmentActivity knows how to manage the support of fragments. OnCreate 方法替换为以下代码:Replace the OnCreate method with the following code:

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);
    ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
    FlashCardDeck flashCards = new FlashCardDeck();
}

此代码执行以下操作:This code does the following:

  1. 设置main.axml布局资源中的视图。Sets the view from the Main.axml layout resource.

  2. 从布局中检索对 ViewPager 的引用。Retrieves a reference to the ViewPager from the layout.

  3. 实例化一个新的 FlashCardDeck 作为数据源。Instantiates a new FlashCardDeck as the data source.

生成并运行此代码时,应会看到类似于以下屏幕截图的显示:When you build and run this code, you should see a display that resembles the following screenshot:

带有空 ViewPager 的 FlashCardPager 应用程序的屏幕截图Screenshot of FlashCardPager app with empty ViewPager

此时,ViewPager 为空,因为缺少用于填充 ViewPager的片段,并且缺少用于从FlashCardDeck中的数据创建这些片段的适配器。At this point, the ViewPager is empty because it is lacking the fragments that are used populate the ViewPager, and it is lacking an adapter for creating these fragments from the data in FlashCardDeck.

在以下部分中,将创建一个 FlashCardFragment 以实现每个闪存卡的功能,并创建一个 FragmentPagerAdapterViewPager 连接到从 FlashCardDeck中的数据创建的片段。In the following sections, a FlashCardFragment is create to implement the functionality of each flash card, and a FragmentPagerAdapter is created to connect the ViewPager to the fragments created from data in the FlashCardDeck.

创建片段Create the Fragment

每个闪存卡将由名为 FlashCardFragment的 UI 片段进行管理。Each flash card will be managed by a UI fragment called FlashCardFragment. FlashCardFragment的视图将显示单个闪存卡中包含的信息。FlashCardFragment's view will display the information contained with a single flash card. FlashCardFragment 的每个实例都将由 ViewPager承载。Each instance of FlashCardFragment will be hosted by the ViewPager. FlashCardFragment的视图将包含显示闪存卡问题文本的 TextViewFlashCardFragment's view will consist of a TextView that displays the flash card problem text. 此视图将实现一个事件处理程序,该处理程序使用 Toast 来显示用户点击闪存卡问题时的答案。This view will implement an event handler that uses a Toast to display the answer when the user taps the flash card question.

创建 FlashCardFragment 布局Create the FlashCardFragment Layout

必须先定义其布局,才能实现 FlashCardFragmentBefore FlashCardFragment can be implemented, its layout must be defined. 此布局是单个片段的片段容器布局。This layout is a fragment container layout for a single fragment. 向名为flashcard_layout. main.axml资源/布局添加新的 Android 布局。Add a new Android layout to Resources/layout called flashcard_layout.axml. 打开Resources/layout/flashcard_layout ,并将其内容替换为以下代码:Open Resources/layout/flashcard_layout.axml and replace its contents with the following code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/flash_card_question"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@android:style/TextAppearance.Large"
            android:textSize="100sp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Question goes here" />
    </RelativeLayout>

此布局定义单个闪存卡片段;每个片段都包含使用大(100sp)字体显示数学问题的 TextViewThis layout defines a single flash card fragment; each fragment is comprised of a TextView that displays a math problem using a large (100sp) font. 此文本在闪存卡上垂直和水平居中。This text is centered vertically and horizontally on the flash card.

创建初始 FlashCardFragment 类Create the Initial FlashCardFragment Class

添加一个名为FlashCardFragment.cs的新文件,并将其内容替换为以下代码:Add a new file called FlashCardFragment.cs and replace its contents with the following code:

using System;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;

namespace FlashCardPager
{
    public class FlashCardFragment : Android.Support.V4.App.Fragment
    {
        public FlashCardFragment() { }

        public static FlashCardFragment newInstance(String question, String answer)
        {
            FlashCardFragment fragment = new FlashCardFragment();
            return fragment;
        }
        public override View OnCreateView (
            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View view = inflater.Inflate (Resource.Layout.flashcard_layout, container, false);
            TextView questionBox = (TextView)view.FindViewById (Resource.Id.flash_card_question);
            return view;
        }
    }
}

此代码会将用于显示闪存卡的基本 Fragment 定义存根。This code stubs out the essential Fragment definition that will be used to display a flash card. 请注意,FlashCardFragment 派生自 Android.Support.V4.App.Fragment中定义的 Fragment 的支持库版本。Note that FlashCardFragment is derived from the support library version of Fragment defined in Android.Support.V4.App.Fragment. 构造函数为空,以便 newInstance 工厂方法用于创建新的 FlashCardFragment 而不是构造函数。The constructor is empty so that the newInstance factory method is used to create a new FlashCardFragment instead of a constructor.

OnCreateView 生命周期方法创建并配置 TextViewThe OnCreateView lifecycle method creates and configures the TextView. 它增加片段的 TextView 布局,并将膨胀的 TextView 返回给调用方。It inflates the layout for the fragment's TextView and returns the inflated TextView to the caller. LayoutInflaterViewGroup 会传递到 OnCreateView,以便它能够使布局膨胀。LayoutInflater and ViewGroup are passed to OnCreateView so that it can inflate the layout. savedInstanceState 捆绑包含 OnCreateView 用于从保存状态重新创建 TextView 的数据。The savedInstanceState bundle contains data that OnCreateView uses to recreate the TextView from a saved state.

通过调用 inflater.Inflate来显式放大片段的视图。The fragment's view is explicitly inflated by the call to inflater.Inflate. container 参数是视图的父级,而 false 标志指示 inflater 转换过程避免将放大视图添加到视图的父级(在本演练后面 ViewPager 调用的适配器的 GetItem 方法时,将添加该视图)。The container argument is the view's parent, and the false flag instructs the inflater to refrain from adding the inflated view to the view's parent (it will be added when ViewPager call's the adapter's GetItem method later in this walkthrough).

向 FlashCardFragment 添加状态代码Add State Code to FlashCardFragment

与活动一样,片段有一个用于保存和检索其状态的 BundleLike an Activity, a fragment has a Bundle that it uses to save and retrieve its state. FlashCardPager中,此 Bundle 用于保存相关闪存卡的问题和答案文本。In FlashCardPager, this Bundle is used to save the question and answer text for the associated flash card. FlashCardFragment.cs中,将以下 Bundle 项添加到 FlashCardFragment 类定义的顶部:In FlashCardFragment.cs, add the following Bundle keys to the top of the FlashCardFragment class definition:

private static string FLASH_CARD_QUESTION = "card_question";
private static string FLASH_CARD_ANSWER = "card_answer";

修改 newInstance 工厂方法,使其创建 Bundle 对象,并使用上面的键将传递的问题和答案文本存储在片段中,并将其实例化:Modify the newInstance factory method so that it creates a Bundle object and uses the above keys to store the passed question and answer text in the fragment after it is instantiated:

public static FlashCardFragment newInstance(String question, String answer)
{
    FlashCardFragment fragment = new FlashCardFragment();

    Bundle args = new Bundle();
    args.PutString(FLASH_CARD_QUESTION, question);
    args.PutString(FLASH_CARD_ANSWER, answer);
    fragment.Arguments = args;

    return fragment;
}

修改片段生命周期方法 OnCreateView 从传入的捆绑包中检索此信息,并将问题文本加载到 TextBox中:Modify the fragment lifecycle method OnCreateView to retrieve this information from the passed-in Bundle and load the question text into the TextBox:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    string question = Arguments.GetString(FLASH_CARD_QUESTION, "");
    string answer = Arguments.GetString(FLASH_CARD_ANSWER, "");

    View view = inflater.Inflate(Resource.Layout.flashcard_layout, container, false);
    TextView questionBox = (TextView)view.FindViewById(Resource.Id.flash_card_question);
    questionBox.Text = question;

    return view;
}

此处不使用 answer 变量,但稍后在将事件处理程序代码添加到此文件时将使用它。The answer variable is not used here, but it will be used later when event handler code is added to this file.

创建适配器Create the Adapter

ViewPager 使用位于 ViewPager 与数据源之间的适配器控制器对象(请参阅 ViewPager适配器文章中的图)。ViewPager uses an adapter controller object that sits between the ViewPager and the data source (see the illustration in the ViewPager Adapter article). 若要访问此数据,ViewPager 要求你提供从 PagerAdapter派生的自定义适配器。To access this data, ViewPager requires that you provide a custom adapter derived from PagerAdapter. 由于本示例使用片段,因此它使用 FragmentPagerAdapterFragmentPagerAdapter 派生自 PagerAdapterBecause this example uses fragments, it uses a FragmentPagerAdapterFragmentPagerAdapter is derived from PagerAdapter. FragmentPagerAdapter 表示每个页面作为 Fragment,只要用户可以返回到页面,就会永久保留在片段管理器中。FragmentPagerAdapter represents each page as a Fragment that is persistently kept in the fragment manager for as long as the user can return to the page. 当用户 swipes ViewPager的页时,FragmentPagerAdapter 将从数据源中提取信息,并使用它来创建 Fragment以便显示 ViewPagerAs the user swipes through pages of the ViewPager, the FragmentPagerAdapter extracts information from the data source and uses it to create Fragments for the ViewPager to display.

实现 FragmentPagerAdapter时,必须重写以下内容:When you implement a FragmentPagerAdapter, you must override the following:

  • 计数– 只读属性,该属性返回可用的视图(页)数。Count – Read-only property that returns the number of views (pages) available.

  • GetItem – 返回要为指定页显示的片段。GetItem – Returns the fragment to display for the specified page.

添加一个名为FlashCardDeckAdapter.cs的新文件,并将其内容替换为以下代码:Add a new file called FlashCardDeckAdapter.cs and replace its contents with the following code:

using System;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;

namespace FlashCardPager
{
    class FlashCardDeckAdapter : FragmentPagerAdapter
    {
        public FlashCardDeckAdapter (Android.Support.V4.App.FragmentManager fm, FlashCardDeck flashCards)
            : base(fm)
        {
        }

        public override int Count
        {
            get { throw new NotImplementedException(); }
        }

        public override Android.Support.V4.App.Fragment GetItem(int position)
        {
            throw new NotImplementedException();
        }
    }
}

此代码会将必要的基本 FragmentPagerAdapter 实现。This code stubs out the essential FragmentPagerAdapter implementation. 在以下部分中,这些方法中的每一个都被替换为工作代码。In the following sections, each of these methods is replaced with working code. 构造函数的目的是将片段管理器传递到 FlashCardDeckAdapter的基类构造函数。The purpose of the constructor is to pass the fragment manager to the FlashCardDeckAdapter's base class constructor.

实现适配器构造函数Implement the Adapter Constructor

当应用程序实例化 FlashCardDeckAdapter时,它将提供一个对片段管理器和一个实例化 FlashCardDeck的引用。When the app instantiates the FlashCardDeckAdapter, it supplies a reference to the fragment manager and an instantiated FlashCardDeck. FlashCardDeckAdapter.cs中,将以下成员变量添加到 FlashCardDeckAdapter 类的顶部:Add the following member variable to the top of the FlashCardDeckAdapter class in FlashCardDeckAdapter.cs:

public FlashCardDeck flashCardDeck;

将以下代码行添加到 FlashCardDeckAdapter 构造函数:Add the following line of code to the FlashCardDeckAdapter constructor:

this.flashCardDeck = flashCards;

下面这行代码存储 FlashCardDeckAdapter 将使用的 FlashCardDeck 实例。This line of code stores the FlashCardDeck instance that the FlashCardDeckAdapter will use.

实现计数Implement Count

Count 实现相对简单:返回闪存卡中纸牌的卡数。The Count implementation is relatively simple: it returns the number of flash cards in the flash card deck. Count 替换为以下代码:Replace Count with the following code:

public override int Count
{
    get { return flashCardDeck.NumCards; }
}

FlashCardDeckNumCards 属性返回数据集中的闪存卡数(碎片数)。The NumCards property of FlashCardDeck returns the number of flash cards (number of fragments) in the data set.

实现 GetItemImplement GetItem

GetItem 方法返回与给定位置关联的片段。The GetItem method returns the fragment associated with the given position. 为闪存卡中的某个位置调用 GetItem 时,它将返回一个 FlashCardFragment 配置为在该位置显示闪存卡问题。When GetItem is called for a position in the flash card deck, it returns a FlashCardFragment configured to display the flash card problem at that position. GetItem 方法替换为以下代码:Replace the GetItem method with the following code:

public override Android.Support.V4.App.Fragment GetItem(int position)
{
    return (Android.Support.V4.App.Fragment)
        FlashCardFragment.newInstance (
            flashCardDeck[position].Problem, flashCardDeck[position].Answer);
}

此代码执行以下操作:This code does the following:

  1. FlashCardDeck 中查找指定位置的数学问题字符串。Looks up the math problem string in the FlashCardDeck deck for the specified position.

  2. FlashCardDeck 中查找指定位置的答案字符串。Looks up the answer string in the FlashCardDeck deck for the specified position.

  3. 调用 FlashCardFragment 工厂方法 newInstance,并传入闪存卡问题和答案字符串。Calls the FlashCardFragment factory method newInstance, passing in the flash card problem and answer strings.

  4. 创建并返回一个新的闪存卡 Fragment,其中包含该位置的问题和答案文本。Creates and returns a new flash card Fragment that contains the question and answer text for that position.

ViewPagerposition呈现 Fragment 时,它将显示包含闪存卡中位于 position 的数学问题字符串的 TextBoxWhen the ViewPager renders the Fragment at position, it displays the TextBox containing the math problem string residing at position in the flash card deck.

将适配器添加到 ViewPagerAdd the Adapter to the ViewPager

现在,FlashCardDeckAdapter 已实现,接下来可以将其添加到 ViewPager中。Now that the FlashCardDeckAdapter is implemented, it's time to add it to the ViewPager. MainActivity.cs中,将以下代码行添加到 OnCreate 方法的末尾:In MainActivity.cs, add the following line of code to the end of the OnCreate method:

FlashCardDeckAdapter adapter =
    new FlashCardDeckAdapter(SupportFragmentManager, flashCards);
viewPager.Adapter = adapter;

此代码将实例化 FlashCardDeckAdapter,并传入第一个参数中的 SupportFragmentManagerThis code instantiates the FlashCardDeckAdapter, passing in the SupportFragmentManager in the first argument. (FragmentActivity 的 SupportFragmentManager 属性用于获取对 FragmentManager 的引用 – 有关 FragmentManager的详细信息,请参阅管理片段。)(The SupportFragmentManager property of FragmentActivity is used to get a reference to the FragmentManager – for more information about the FragmentManager, see Managing Fragments.)

核心实现现已完成 – 生成并运行应用。The core implementation is now complete – build and run the app. 屏幕上会显示 "闪存卡" 面板的第一个图像,如接下来的屏幕截图中所示。You should see the first image of the flash card deck appear on the screen as shown on the left in the next screenshot. 向左轻扫可查看更多的闪存卡,并向右轻扫可通过闪光灯向后移动:Swipe left to see more flash cards, then swipe right to move back through the flash card deck:

不带寻呼指标的 FlashCardPager 应用的示例屏幕截图Example screenshots of FlashCardPager app without pager indicators

添加寻呼指示器Add a Pager Indicator

这一最小 ViewPager 实现将显示卡片组中的每个闪存卡,但不会指示用户在卡片组中的位置。This minimal ViewPager implementation displays each flash card in the deck, but it provides no indication as to where the user is within the deck. 下一步是添加 PagerTabStripThe next step is to add a PagerTabStrip. PagerTabStrip 向用户通知显示了哪个问题号,并通过显示上一张和下一闪存卡的提示来提供导航上下文。The PagerTabStrip informs the user as to which problem number is displayed and provides navigation context by displaying a hint of the previous and next flash cards.

打开Resources/layout/main.axml ,并将 PagerTabStrip 添加到布局:Open Resources/layout/Main.axml and add a PagerTabStrip to the layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

  <android.support.v4.view.PagerTabStrip
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="top"
      android:paddingBottom="10dp"
      android:paddingTop="10dp"
      android:textColor="#fff" />

</android.support.v4.view.ViewPager>

当你生成并运行应用时,你应该会看到显示在每个闪存卡顶部的空 PagerTabStripWhen you build and run the app, you should see the empty PagerTabStrip displayed at the top of each flash card:

不带文本的 PagerTabStrip 的特写Closeup of PagerTabStrip without text

显示标题Display a Title

若要将标题添加到每个页选项卡,请在适配器中实现 GetPageTitleFormatted 方法。To add a title to each page tab, implement the GetPageTitleFormatted method in the adapter. ViewPager 调用 GetPageTitleFormatted (如果已实现)来获取描述指定位置上页面的标题字符串。ViewPager calls GetPageTitleFormatted (if implemented) to obtain the title string that describes the page at the specified position. 将以下方法添加到FlashCardDeckAdapter.cs中的 FlashCardDeckAdapter 类:Add the following method to the FlashCardDeckAdapter class in FlashCardDeckAdapter.cs:

public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
    return new Java.Lang.String("Problem " + (position + 1));
}

此代码将闪存卡中的位置转换为问题编号。This code converts the position in the flash card deck to a problem number. 生成的字符串转换为返回到 ViewPager的 Java StringThe resulting string is converted into a Java String that is returned to the ViewPager. 当你通过此新方法运行应用时,每个页面都会在 PagerTabStrip中显示问题编号:When you run the app with this new method, each page displays the problem number in the PagerTabStrip:

屏幕截图,其中显示了每个页面上方显示的问题编号Screenshots of FlashCardPager with the problem number displayed above each page

您可以来回切换,以查看每个闪存卡顶部显示的 "闪存卡" 中的问题号。You can swipe back and forth to see the problem number in the flash card deck that is displayed at the top of each flash card.

处理用户输入Handle User Input

FlashCardPagerViewPager中提供一系列基于片段的闪存卡,但它尚不能显示每个问题的答案。FlashCardPager presents a series of fragment-based flash cards in a ViewPager, but it does not yet have a way to reveal the answer for each problem. 在本部分中,将向 FlashCardFragment 添加一个事件处理程序,以便在用户点击闪存卡问题文本时显示答案。In this section, an event handler is added to the FlashCardFragment to display the answer when the user taps on the flash card problem text.

打开FlashCardFragment.cs ,并将以下代码添加到 OnCreateView 方法的末尾,然后将视图返回给调用方:Open FlashCardFragment.cs and add the following code to the end of the OnCreateView method just before the view is returned to the caller:

questionBox.Click += delegate
{
    Toast.MakeText(Activity.ApplicationContext,
            "Answer: " + answer, ToastLength.Short).Show();
};

Click 事件处理程序会在用户点击 TextBox时显示 Toast 中的答案。This Click event handler displays the answer in a Toast that appears when the user taps the TextBox. 在从传递给 OnCreateView的捆绑中读取状态信息时,先前初始化了 answer 变量。The answer variable was initialized earlier when state information was read from the Bundle that was passed to OnCreateView. 构建并运行应用,然后点击每个闪存卡上的问题文本以查看答案:Build and run the app, then tap the problem text on each flash card to see the answer:

点击数学问题时,FlashCardPager 应用 Toast 的屏幕截图Screenshots of FlashCardPager app Toasts when math problem is tapped

本演练中介绍的FlashCardPager使用派生自 FragmentActivityMainActivity,但你也可以从 AppCompatActivity 派生 MainActivity (这也会为管理片段提供支持)。The FlashCardPager presented in this walkthrough uses a MainActivity derived from FragmentActivity, but you can also derive MainActivity from AppCompatActivity (which also provides support for managing fragments). 若要查看 AppCompatActivity 示例,请参阅示例库中的FlashCardPagerTo view an AppCompatActivity example, see FlashCardPager in the Sample Gallery.

总结Summary

本演练提供了有关如何使用 Fragment生成基于基本 ViewPager的应用的分步示例。This walkthrough provided a step-by-step example of how to build a basic ViewPager-based app using Fragments. 其中显示了一个包含闪存卡问题和答案的示例数据源、一个用于显示闪存卡的 ViewPager 布局以及一个将 ViewPager 连接到数据源的 FragmentPagerAdapter 子类。It presented an example data source containing flash card questions and answers, a ViewPager layout to display the flash cards, and a FragmentPagerAdapter subclass that connects the ViewPager to the data source. 为了帮助用户浏览闪存卡,包括说明如何添加 PagerTabStrip 以在每一页的顶部显示问题编号的说明。To help the user navigate through the flash cards, instructions were included that explain how to add a PagerTabStrip to display the problem number at the top of each page. 最后,添加了事件处理代码以显示用户点击闪存卡问题时的答案。Finally, event handling code was added to display the answer when the user taps on a flash card problem.