当设计程序来支持各种不一样的屏幕尺寸时,可以在不同的布局中重用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. 重温委托(delegate)和事件(event)

    1.delegate是什么 某种意义上来讲,你可以把delegate理解成C语言中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作 ...

  2. WPF自定义ListBox样式

    <!--竖向--> <Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}"> ...

  3. 水晶易表 Xcelsius 2008 安装指南 完美支持office2010(亲手体验)

    Xcelsius2008水晶易表是一款很好用的软件.网上已经有破解方法,大家能够尝试一下这款经典软件了. 可是网上对于安装破解过程介绍的不详细或者纷乱,今天我汇总了全部的方法最终成功的安装上了,而且支 ...

  4. GDAL切割重采样遥感图像

    一个小测试程序开发全过程实录,完全新手入门级的实例,如果你还在为处理大影像而发愁,来试试这个称手的工具吧. Imagec 开发日记 2013-6-25 需求: 影像数据切割,重采样 数据切割的要求是简 ...

  5. wamp5中的apache不能启动,80端口被占用

    在wamp中apache中的httpd.conf文件中 端口文件设置为8080 #Listen 12.34.56.78:8080Listen 8080

  6. Eclipse常用设置汇总

    设置编码: . 设置字体: 依次展开 Window->Preferences->Java->Code Style->Formatter  在右边窗口中找到Edit ·找到Lin ...

  7. 【python】按行切分文本文件

    python脚本利用shell命令来实现文本的操作, 这些命令大大减少了我们的代码量. 比如按行切分文件并返回切分后得到的文件列表,可以利用内建的split命令进行切分.为了返回得到的文件列表名,可以 ...

  8. DSL简介(转)

    DSL编程:有人将DSL编程称之为声明式(Declarative)编程.DSL是在模型之上建立的一种更加灵活的对 模型化的理解和使用方式.语义模型是DSL的核心.内部DSL:用通用语言的语法表示DSL ...

  9. windbg更改cmd的token提升其特权

    采用windbg 调试xp. 执行cmd.whoami检查权限如下面: 以下要做的就是把cmd.exe 的token值用system的token替换. 1.  Ctrl + break ,windbg ...

  10. Morphia采用

    Morphia配合mongoDB喜欢Hibernate关系型数据库.也能够想到Morphia于MongoDB它调用上述的基础上,mongoDB语法. 于java直接通话Morphia的api它会变得更 ...