当设计程序来支持各种不一样的屏幕尺寸时,可以在不同的布局中重用fragment来根据可用的屏幕大小来优化用户体验。

例如,在手机上可能使用一个fragment来使用单窗口用户体验比较合适。但是,你可能想在平板上边靠边的设置两个fragment因为有更宽的屏幕向用户展示更多信息。

图1.两个fragment,同一个activity在不同的屏幕大小上的不同展现形式。在大屏幕上,两个fragment边靠边,但是在手机设备上,一次只显示一个fragment因此fragment在用户切换的时候替换另一个。

为了创建动态的体验, FragmentManager类提供了方法可以在运行时添加,删除,替换activity中的fragment。

在运行时向activity添加fragment

不仅仅可以在activity布局文件中定义fragment(前面介绍了使用<fragment>元素),也可以在activity运行时加入fragment。如果计划在activity运行时改变fragment,这个很有必要。

要处理添加删除fragment,可以使用FragmentManager来创建一个FragmentTransation,它提供了API来添加,替换和fragment的其他事务。

如果activity允许fragment删除或者替换,应该在activity的onCreate()方法中添加fragment的初始化信息。

处理fragment有一个重要的规则,特别是在运行时添加的fragment:fragment在布局中必须有一个View容器。

下面的布局是上一篇中布局的一个变形,这里一次只显示一个fragment。为了用一个fragment替换另一个,这个activity的布局包含一个空的FrameLayout作为fragment的容器。

这个文件名和前面一篇中布局的文件名是一样的,但是布局文件夹没有large标识,所以这个布局使用在小屏幕上因为小屏幕不需要同时显示两个fragment。

res/layout/news_articles.xml:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

在activity中,使用Support Library中的API getSupportFragmentManager()来获得FragmentManager.然后调用beginTransaction()来创建一个FragmentTransaction再调用add()添加一个fragment。

可以使用一个FragmentTransaction来处理多个activity的fragment rransaction。当准备好执行这些改变后,调用commit()。

例如,这里展示了如何把fragment加到前一个布局上:

 import android.os.Bundle;
import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles); //检查activity的布局是使用fragment_container FrameLayout的版本
if (findViewById(R.id.fragment_container) != null) { // 但是,如果是从前一个状态恢复的话
// 我们不需要做任何事情,直接返回就行了,否则就会重叠fragments。
if (savedInstanceState != null) {
return;
} //创建一个Fragment实例
HeadlinesFragment firstFragment = new HeadlinesFragment(); //有可能activity是从Intent中的特殊指令创建的,
//把Intent的extras当参数传递给fragment
firstFragment.setArguments(getIntent().getExtras()); // 把fragment加入到'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}

因为fragment是在运行时加入到FrameLayout的(不是在activity的布局文件中用<fragment>定义的),activity就可以移出这个fragment然后用一个不同的替换它。

用一个fragment替换另一个

换掉一个fragment的方法和添加一个相似,但是需要使用replace()方法,而不是add()

记住当执行fragment切换时,例如添加或者删除,经常要允许用户切换回去来恢复这些改变。为了允许用户在fragment切换时切换回去,应该在提交FragmentTransaction之前调用addToBackStack()。

注意:当移除或者替换一个fragment然后加到切换的返回堆栈中时,被移除的fragment是Stopped状态(并不是Destroyed)。如果用户切换回去来恢复fragment,它就重启。如果没有把它加到返回堆栈中,fragment被移除或者替换时就销毁了。

用一个fragment替换另一个的例子:

 //创建一个fragment,然后把应该展示的文章的参数传给它
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); //用这个fragment替换掉fragment_container view 中的东西,
//然后把transaction加到返回堆栈中,这样用户就可以切换回去了
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null); //提交transaction
transaction.commit();

addToBackStack()方法带一个可选的字符串参数,用来指定一个唯一的transaction名字。这个名字并不是必需的除非需要用FragmentManager.BackStackEntryAPI的一些特使操作。

上一篇:Android - 用Fragments实现动态UI - 创建Fragment

下一篇:Android - 用Fragments实现动态UI - 和其他Fragments通信

Android - 用Fragments实现动态UI - 创建灵活的UI的更多相关文章

  1. Android - 用Fragments实现动态UI - 创建Fragment

    你可以把fragment当作activity中的一个活动模块,它有自己的生命周期,自己接收输入消息,可以在activity运行的时候添加和删除(就像可以在其他activity中重用的"子ac ...

  2. Android - 用Fragments实现动态UI

    要在Android上实现动态的多窗口的用户交互界面,需要把UI组建和activity放到modules中, 这样才能划进划出activity.可是使用Fragment类来创建modules,它就像一个 ...

  3. Android - 用Fragments实现动态UI - 使用Android Support Library

    Android Support Library提供了一个带有API库的JAR文件来让你可以在使用最新的Android API的同时也也已在早期版本的Android上运行.例如,Support Libr ...

  4. Android - 用Fragments实现动态UI - 和其他Fragments通信

    为了重用Fragment UI组件,应该把每个都设计为它自有的模块组件并且有自己的布局和行为.一旦定义了这些可重用的Fragment,你可以把它们和一个activity关联然后和程序的逻辑一起实现上层 ...

  5. Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7867340 在前面一篇文章中,我们分析了And ...

  6. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

  7. Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应 ...

  8. android脚步---如何看log之程序停止运行,和UI线程和非UI线程之间切换

    经常运行eclipse时,烧到手机出现,“停止运行”,这时候得通过logcat查log了.一般这种情况属于FATAL EXCEPTION,所以检索FATAL 或者 EXCEPTION,然后往下看几行 ...

  9. vue-cli@3.x之使用vue ui创建项目-来自一个战五渣的体验

    1. 全局安装vue-cli yarn global add @vue/cli // 检查安装是否成功 vue -V // 3.2.2 2. 初始化 vue ui 执行命令 vue ui 2.1 该命 ...

随机推荐

  1. 10招让你成为杰出的Java程序员(转)

    如果你是一个热衷于技术的 Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出. 1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Ob ...

  2. hdu1028(整数划分问题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028 整数划分问题 整数划分 --- 一个老生长谈的问题: 描述 整数划分是一个经典的问题.请写一个程 ...

  3. 【剑指offer】面试题24:二叉搜索树的兴许前序遍历序列

    分析: 前序: 根 左 右 后序: 左 由 根 二叉搜索树: 左 < 根 < 右 那么这就非常明显了. def ifpost(postArray, start, end): #one or ...

  4. Android -&gt; 怎样避免Handler引起内存泄露

    很多其它内容,可訪问个人博客www.liangfeizc.com 错误代码 假设在Activiy中通过内部类(Runnable)的方式定义了一个变量runnable, final Runnable r ...

  5. C++:抽象基类和纯虚函数的理解

    转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...

  6. (转)ikvmc的使用

    IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.), ...

  7. poj1935(树形dp)

    题目链接:http://poj.org/problem?id=1935 题意:带边权的树,给点一个根,问从根出发遍历某些点,所需的最小花费. 分析:树上任意两点的路径是唯一的,直接dfs一遍,可以得出 ...

  8. 京东商城招聘自动调价系统架构师 T4级别

    岗位级别:T4 岗位职责: 1.负责自动调价系统的架构设计 2.负责自动调价的预测.相关性算法设计 3.核心代码编写,代码review 任职要求: 1.熟悉数据挖掘.机器学习理论和算法 2.熟悉海量数 ...

  9. AndroidMainFest.xml file missing!

    今天在导入项目的时候出现了这种错误: 仅仅须要一步 就搞定: projecct --->  clean  又一次编译一下就可以搞定了.

  10. Extjs4.0.7 实现Grid的嵌套

    网上相关资料非常少,我看过的大多是Extjs 3.0 急以前版本的解决方案. 比如:http://mikhailstadnik.com/ext/examples/nested-grid.htm  (E ...