【Android】11.6 Fragments基本用法示例

分类:C#、Android、VS2015;

创建日期:2016-02-22

一、简介

该例子演示了如何使用两个fragment创建双区域布局的activity(纵向和横向)。在这个activity包含的两个fragment中,一个fragment用来显示笑话列表的标题,另一个fragment用来在列表项被选中时显示该笑话的详细内容。同时,该例子也演示了如何基于不同屏幕配置(纵向放置的肖像模式、横向放置的景观模式)分别提供不同的fragment。

二、运行效果

 

注意:【Ctrl】+【F11】是控制模拟器“竖屏/横屏”转换的快捷键。

下面是按【Ctrl】+【F11】将模拟器从竖屏旋转为横屏后看到的效果:

三、主要创建步骤

1、添加竖屏模式的ch1104_Main.xaml文件

在Resources/layout文件夹下添加该文件。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <fragment
      class="MyDemos.SrcDemos.ch1104FragmentTitles"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
      android:id="@+id/titles" />
</FrameLayout>

当屏幕被置于纵向时,系统会自动适应此布局。

这个布局只包含了TitlesFragment。这就意味着,当设备置于纵向时,只有笑话标题列表是可见的。因此,当用户点击某一个列表项时,应用程序将开启一个新的activity来显示笑话的内容,而不是直接在第二个fragment中来显示它。

在fragment类中,首先显示笑话标题的TitlesFragment。这个fragment继承于ListFragment,靠它来处理笑话标题列表的工作。

2、添加横屏模式的ch1104_Main.axml文件

在Resources/layout-land文件夹下添加该文件。

注意改文件名必须和竖屏模式的文件名相同。XML代码如下:

<?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
        class="MyDemos.SrcDemos.ch1104FragmentTitles"
        android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:id="@+id/titles" />
    <FrameLayout
        android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:id="@+id/details" />
</LinearLayout>

activity一旦载入此布局,系统就实例化TitlesFragment(列出笑话标题),同时在屏幕右方的FrameLayout中的fragment显示笑话内容。笑话内容刚开始是空字符串,当用户从列表中选择一项时,fragment才被置于FrameLayout中,这样做是为了不让其大量占用内存。

由于并不是所有的屏幕都足以能并排显示笑话列表和详细内容,所以这个布局仅适用于屏幕横向放置的情况。

切换到【设计】视图看到的界面截图如下:

3、添加ch1104ActivityMain.cs文件

在SrcDemos文件夹下添加该文件,模板选择【Activity】。

using Android.App;
using Android.OS;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "【例11-4】Fragment基本用法")]
    public class ch1104ActivitMain : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.ch1104_Main);
        }
    }

    public class ch1104Joke
    {
        public static string[] Titles = { "笑话1", "笑话2", "笑话3", "笑话4", "笑话5" };
        public static string[] Dialogue = {
            "笑话1:一男子在闹市骑摩托撞昏了一个陌生的老汉! 男子惊吓的不知所措!围观群众越来越多!突然,该男抱住老汉,声泪俱下的喊道:“爹,你等着我,我这就去给你找医生!”说后,就跑掉了。。。老汉挣扎着愤怒的喊道:“给老子回来!”众人纷纷感慨:“这儿子当的真孝顺!” ",
            "笑话2:小明考试回家,妈妈问他:“考的咋呀?”小明说:“只有一道题错了!!”妈妈问:“啥题?”小明说:“问3乘7等于几?”妈妈问:“你说等于几”小明说:“我当时不管三七二十一填了个等于40!”",
            "笑话3:昨天微信上收到一条打招呼的,打开一看,是个MM。MM:“好无聊啊!”我:“我也好无聊啊!”(期待她叫我出去玩。)MM:“无聊的话你放个屁追着玩啊!”我二话不说就把她给删了。",
            "笑话4:某日,一个对中文略知一二的老外去某工厂参观。半路上厂长说:“对不起,我去方便一下。”老外不懂这句中文,问翻译:“方便是什么意思。”翻译说,“就是去厕所。”老外:“哦……”参观结束,厂长热情地对老外说:“下次你方便的时候一起吃饭!”老外一脸不高兴,用生硬的中文说:“我在方便的时候从来不吃饭!”",
            "笑话5:一位女教师在黑板上画了个苹果,问同学们:“这是什么?”结果,大家回答:“屁股!”女老师哭着找校长,校长十分生气,来到教室:“你们怎么把老师给气哭了?”又看了看黑板:“哟,你们还在黑板上画了个屁股!” "
        };
    }
}

在SrcDemos文件夹下添加该文件,模板选择【Fragment】。

DetailsFragment在TitlesFragment的列表项被选中时显示笑话内容。

using System;
using Android.App;
using Android.OS;
using Android.Util;
using Android.Views;
using Android.Widget;

namespace MyDemos.SrcDemos
{
    public class ch1104FragmentDetails : Fragment
    {
        public int ShownIndex { get { return Arguments.GetInt("current_id", 0); } }

        public static ch1104FragmentDetails NewInstance(int playId)
        {
            var detailsFrag = new ch1104FragmentDetails { Arguments = new Bundle() };
            detailsFrag.Arguments.PutInt("current_id", playId);
            return detailsFrag;
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            if (container == null)
            {
                // 如果当前布局中没有container, 没有必要创建视图,所以返回null
                return null;
            }
            var scrollView = new ScrollView(Activity);
            var text = new TextView(Activity);
            var padding = Convert.ToInt32(TypedValue.ApplyDimension(ComplexUnitType.Dip, 4, Activity.Resources.DisplayMetrics));
            text.SetPadding(padding, padding, padding, padding);
            text.TextSize = 18;
            text.Text = ch1104Joke.Dialogue[ShownIndex];
            scrollView.AddView(text);
            return scrollView;
        }
    }
}

5、添加ch1104FragmentTitles.cs文件

在SrcDemos文件夹下添加该文件,模板选择【Fragment】。

using Android.App;
using Android.Content;
using Android.OS;
using Android.Views;
using Android.Widget;

namespace MyDemos.SrcDemos
{
    public class ch1104FragmentTitles : ListFragment
    {
        private bool isDualPane;
        private int currentCheckPosition = 0;

        public override void OnActivityCreated(Bundle savedInstanceState)
        {
            base.OnActivityCreated(savedInstanceState);

            ListAdapter = new ArrayAdapter<string>(Activity,
                Android.Resource.Layout.SimpleListItemActivated1, ch1104Joke.Titles);

            var detailsFrame = Activity.FindViewById<View>(Resource.Id.details);
            isDualPane = detailsFrame != null && detailsFrame.Visibility == ViewStates.Visible;

            if (savedInstanceState != null)
            {
                currentCheckPosition = savedInstanceState.GetInt("current_id", 0);
            }

            if (isDualPane)
            {
                ListView.ChoiceMode = ChoiceMode.Single;
                ShowDetails(currentCheckPosition);
            }
        }

        public override void OnSaveInstanceState(Bundle outState)
        {
            base.OnSaveInstanceState(outState);
            outState.PutInt("current_id", currentCheckPosition);
        }

        public override void OnListItemClick(ListView l, View v, int position, long id)
        {
            ShowDetails(position);
        }

        /// <summary>
        /// 显示所选项的详细信息,或者通过UI中的片段显示,或者启动一个新的活动
        /// </summary>
        /// <param name="index">当前选项的序号</param>
        private void ShowDetails(int index)
        {
            currentCheckPosition = index;
            if (isDualPane)
            {
                ListView.SetItemChecked(index, true);

                // 检查当前显示的是哪个fragment,如果需要,就替换掉它。
                var details = FragmentManager.FindFragmentById(Resource.Id.details) as ch1104FragmentDetails;
                if (details == null || details.ShownIndex != index)
                {
                    details = ch1104FragmentDetails.NewInstance(index);

                    // 执行事务(transaction), 替换已存在的fragment
                    var ft = FragmentManager.BeginTransaction();
                    ft.Replace(Resource.Id.details, details);
                    ft.SetTransition(FragmentTransit.FragmentFade);
                    ft.Commit();
                }
            }
            else
            {
                var intent = new Intent();
                intent.SetClass(Activity, typeof(ch1104ActivityDetails));
                intent.PutExtra("current_id", index);
                StartActivity(intent);
            }
        }
    }
}

注意:当用户点击一个列表项时会产生两个可能的行为,这依赖于两个布局哪个处于激活状态,它要么创建并显示一个新的fragment以在同一个activity中显示笑话内容(添加fragment到FrameLayout),要么启动一个新的activity(在fragment可显示的地方)。

6、添加ch1104ActivityDetails.cs文件

在SrcDemos文件夹下添加该文件,模板选择【Activity】。

DetailsActivity只是在屏幕纵向时,嵌入DetailFragment以显示被选中的笑话。

using Android.App;
using Android.Content;
using Android.OS;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "【例11-4】Fragment基本用法")]
    public class ch1104ActivityDetails : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            if (Resources.Configuration.Orientation == Android.Content.Res.Orientation.Landscape)
            {
                // 如果屏幕是横放的(landscape mode), 由于右侧直接显示笑话内容了,所以不需要此活动
                Finish();
                return;
            }
            var index = Intent.Extras.GetInt("current_id", 0);
            var details = ch1104FragmentDetails.NewInstance(index);
            FragmentManager.BeginTransaction().Add(Android.Resource.Id.Content, details).Commit();
        }
    }
}

注意,如果配置是横向的,这个activity会结束掉自己,使主acitivity可以接管并在TitlesFragment旁显示DetailsFragment。这种情况可能会发生在,用户在纵向时开启了DetailsActivity,但是之后旋转到横向,这会重新启动当前的activity。

OK,这一章就讲到这里了。

时间: 2024-10-13 11:01:21

【Android】11.6 Fragments基本用法示例的相关文章

C++11中function和bind的用法示例

环境Visual Studio 2012,具体代码如下 #include <iostream> #include <functional> #include <string> void PrintNumber(int num) { std::cout << num << std::endl; } struct Printer { void Print(std::string print_str) { std::cout << prin

Android开发:SurfaceView基本用法总结

本文主要讲解如何使用SurfaceView,旨在帮助大家快速上手SurfaceView开发.由于上篇文章<Android开发:SurfaceView基本用法总结及开发问题分享> 排版不佳,所以另起一篇单独介绍SurfaceView的基本用法总结. 转载请注明作者xiong_it和链接:http://blog.csdn.net/xiong_it/article/details/45966309,谢谢! SurfaceView基本介绍 1.系统给SurfaceView提供了一个专门绘图的Surfa

(转载)Android常用的Dialog对话框用法

Android常用的Dialog对话框用法 Android的版本有很多通常开发的时候对话框大多数使用自定义或是 Google提供的V4, V7 兼容包来开发保持各个版本的对话框样式统一,所以这里使用的是V7 包里的AlertDialog. 1 import android.app.ProgressDialog; 2 import android.content.DialogInterface; 3 import android.os.Bundle; 4 import android.os.Sys

oracle中to_date详细用法示例(oracle日期格式转换)

这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 13:45:25为例) 1. 日期和字符转换函数用法(to_date,to_char) select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') as nowTime from dual; //日期转化为字符串 select to_char(sysdate,'

【转】java list用法示例详解

转自:http://www.jb51.net/article/45660.htm java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中,下文对java list用法做了详解. List:元素是有序的(怎么存的就怎么取出来,顺序不会乱),元素可以重复(角标1上有个3,角标2上也可以有个3)因为该集合体系有索引,ArrayList:底层的数据结构使用的是数组结构(数组长度是可变的百分之五十延长)(特点是查询很快,但增删较慢)线程不同步LinkedList:底层的数据结构是链表结构(

Android中各种Adapter的用法

1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView)等地方都需要用到Adapter.如下图直观的表达了Data.Adapter.View三者的关系: Android中所有的Adapter一览: 由图可以看到在Android中与Adapter有关的所有接口.类的完整层级图.在我们使用过程中可以根据自己的需求实现接口或者继承类进行一定的扩展.比较常用的有 BaseAdapter,SimpleA

WPF 高性能位图渲染 WriteableBitmap 及其高性能用法示例

原文:WPF 高性能位图渲染 WriteableBitmap 及其高性能用法示例 WPF 渲染框架并没有对外提供多少可以完全控制渲染的部分,目前可以做的有: D3DImage,用来承载使用 DirectX 各个版本渲染内容的控件 WriteableBitmap,通过一段内存空间来指定如何渲染一个位图的图片 HwndHost,通过承载一个子窗口以便能叠加任何种类渲染的控件 本文将解释如何最大程度压榨 WriteableBitmap 在 WPF 下的性能. 本文内容 如何使用 WriteableBi

openat与open的区别及用法示例

从2.6.16版本开始,GNU/Linux引入opeant系统调用: #define _XOPEN_SOURCE 700 /* Or define _POSIX_C_SOURCE >= 200809 */ #include <fcntl.h> int openat(int dirfd , const char * pathname , int flags , ... /* mode_t mode */); Returns file descriptor on success, or –1

wxpython布局管理部件wx.gridbagsizer用法示例

text = ("This is text box")         panel = wx.Panel(self, -1)         chkAll1 = wx.CheckBox(panel, ID_CHKBOX_CAN_SEL_ALL, u'全选')                chkKnown = wx.CheckBox(panel, ID_CHKBOX_CAN_UNKNOWN, u'不会')         chkUnknow = wx.CheckBox(panel, I