android:碎片的使用方式
介绍了这么多抽象的东西,也是时候应该学习一下碎片的具体用法了。你已经知道,碎 片通常都是在平板开发中才会使用的,因此我们首先要做的就是新建一个平板电脑的模拟 器。由于 4.0 系统的平板模拟器好像存在 bug,这里我就新建一个 4.2 系统的平板模拟器,如 图 4.4 所示。

图 4.4
现在启动这个平板模拟器,效果如图 4.5 所示。

图 4.5
好了,准备工作都完成了,接着新建一个 FragmentTest 项目,然后开始我们的碎片探索
之旅吧。
4.2.1 碎片的简单用法
这里我们准备先写一个最简单的碎片示例来练练手,在一个活动当中添加两个碎片,并
让这两个碎片平分活动空间。
新建一个左侧碎片布局 left_fragment.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"
/>
</LinearLayout>
这个布局非常简单,只放置了一个按钮,并让它水平居中显示。然后新建右侧碎片布局
right_fragment.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is right fragment"
/>
</LinearLayout>
可以看到,我们将这个布局的背景色设置成绿色,并放置了一个 TextView 用于显示一
段文本。接着新建一个 LeftFragment 类,继承自 Fragment。注意,这里可能会有两个不同包 下的 Fragment 供你选择,建议使用 android.app.Fragment,因为我们的程序是面向 Android 4.0 以上系统的,另一个包下的 Fragment 主要是用于兼容低版本的 Android 系统。LeftFragment 的代码如下所示:
public class LeftFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_fragment, container, false);
return view;
}
}
这里仅仅是重写了 Fragment 的 onCreateView()方法,然后在这个方法中通过 LayoutInflater 的 inflate()方法将刚才定义的 left_fragment 布局动态加载进来,整个方法简单明了。接着我 们用同样的方法再新建一个 RightFragment,代码如下所示:
public class RightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
}
基本上代码都是相同的,相信已经没有必要再做什么解释了。接下来修改 activity_main.xml
中的代码,如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/right_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="0dp"
android:layout_height="match_parent" android:layout_weight="1"
/>
</LinearLayout>
可以看到,我们使用了<fragment>标签在布局中添加碎片,其中指定的大多数属性你都
是熟悉的,只不过这里还需要通过 android:name 属性来显式指明要添加的碎片类名,注意一 定要将类的包名也加上。
这样最简单的碎片示例就已经写好了,现在运行一下程序,效果如图 4.6 所示。

图 4.6
正如我们所期待的一样,两个碎片平分了整个活动的布局。不过这个例子实在是太简单
了,在真正的项目中很难有什么实际的作用,因此我们马上来看一看,关于碎片更加高级的 使用技巧。
4.2.2 动态添加碎片
在上一节当中,你已经学会了在布局文件中添加碎片的方法,不过碎片真正的强大之处
在于,它可以在程序运行时动态地添加到活动当中。根据具体情况来动态地添加碎片,你就
可以将程序界面定制得更加多样化。
我们还是在上一节代码的基础上继续完善,新建 another_right_fragment.xml,代码如下 所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00" android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is another right fragment"
/>
</LinearLayout>
这个布局文件的代码和 right_fragment.xml 中的代码基本相同,只是将背景色改成了黄 色,并将显示的文字改了改。然后新建 AnotherRightFragment 作为另一个右侧碎片,代码如
下所示:
public class AnotherRightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.another_right_fragment,
container, false);
return view;
}
}
代码同样非常简单,在 onCreateView()方法中加载了刚刚创建的 another_right_fragment
布局。这样我们就准备好了另一个碎片,接下来看一下如何将它动态地添加到活动当中。修
改 activity_main.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/right_layout" android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<fragment
android:id="@+id/right_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
可以看到,现在将右侧碎片放在了一个 FrameLayout 中,还记得这个布局吗?在上一章 中我们学过,这是 Android 中最简单的一种布局,它没有任何的定位方式,所有的控件都会 摆放在布局的左上角。由于这里仅需要在布局里放入一个碎片,因此非常适合使用 FrameLayout。
之后我们将在代码中替换 FrameLayout 里的内容,从而实现动态添加碎片的功能。修改
MainActivity 中的代码,如下所示:
public class MainActivity extends
Activity implements OnClickListener {
@Override
protected
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new
AnotherRightFragment(); FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.
beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
break;
default:
break;
}
}
}
可以看到,首先我们给左侧碎片中的按钮注册了一个点击事件,然后将动态添加碎片的
逻辑都放在了点击事件里进行。结合代码可以看出,动态添加碎片主要分为 5 步。
1. 创建待添加的碎片实例。
2. 获取到 FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。
3. 开启一个事务,通过调用 beginTransaction()方法开启。
4. 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器的 id
和待添加的碎
片实例。
5. 提交事务,调用 commit()方法来完成。 这样就完成了在活动中动态添加碎片的功能,重新运行程序,可以看到和之前相同的界
面,然后点击一下按钮,效果如图 4.7 所示。

图 4.7
4.2.3 在碎片中模拟返回栈
在上一小节中,我们成功实现了向活动中动态添加碎片的功能,不过你尝试一下就会发
现,通过点击按钮添加了一个碎片之后,这时按下 Back 键程序就会直接退出。如果这里我 们想模仿类似于返回栈的效果,按下 Back 键可以回到上一个碎片,该如何实现呢?
其实很简单,FragmentTransaction 中提供了一个 addToBackStack()方法,可以用于将一 个事务添加到返回栈中,修改 MainActivity 中的代码,如下所示:
public class MainActivity extends Activity implements
OnClickListener {
……
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new
AnotherRightFragment(); FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.
beginTransaction();
transaction.replace(R.id.right_layout,
fragment); transaction.addToBackStack(null); transaction.commit();
break;
default:
break;
}
}
}
这里我们在事务提交之前调用了 FragmentTransaction 的 addToBackStack()方法,它可以 接收一个名字用于描述返回栈的状态,一般传入 null
即可。现在重新运行程序,并点击按钮
将 AnotherRightFragment 添加到活动中,然后按下 Back 键,你会发现程序并没有退出,而 是回到了 RightFragment 界面,再次按下 Back 键程序才会退出。
4.2.4 碎片和活动之间进行通信
虽然碎片都是嵌入在活动中显示的,可是实际上它们的关系并没有那么亲密。你可以看 出,碎片和活动都是各自存在于一个独立的类当中的,它们之间并没有那么明显的方式来直
接进行通信。如果想要在活动中调用碎片里的方法,或者在碎片中调用活动里的方法,应该
如何实现呢?
为了方便碎片和活动之间进行通信,FragmentManager 提供了一个类似于 findViewById()
的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:
RightFragment rightFragment = (RightFragment)
getFragmentManager()
.findFragmentById(R.id.right_fragment);
调用 FragmentManager 的 findFragmentById()方法,可以在活动中得到相应碎片的实例,
然后就能轻松地调用碎片里的方法了。
掌握了如何在活动中调用碎片里的方法,那在碎片中又该怎样调用活动里的方法呢?其 实这就更简单了,在每个碎片中都可以通过调用 getActivity()方法来得到和当前碎片相关联 的活动实例,代码如下所示:
MainActivity activity = (MainActivity) getActivity();
有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要
使用
Context 对象时,也可以使用 getActivity()方法,因为获取到的活动本身就是一个 Context 对象了。
这时不知道你心中会不会产生一个疑问,既然碎片和活动之间的通信问题已经解决了, 那么碎片和碎片之间可不可以进行通信呢?
说实在的,这个问题并没有看上去的复杂,它的基本思路非常简单,首先在一个碎片中 可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样也就实 现了不同碎片之间的通信功能,因此这里我们的答案是肯定的。
android:碎片的使用方式的更多相关文章
- 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
腾讯优测是专业的android自动化测试平台,拥有上千款真机,彻底解决android碎片化问题! 这里我要说的不是闪光灯的硬件特征,也不是说底层驱动的原理,我只是跟大家聊一聊在项目中遇到的一些关于闪光 ...
- android 三种定位方式
http://www.cnblogs.com/oudi/archive/2012/03/22/2411509.html 最近在看android关于定位的方式,查了很多资料,也做了相关实验,在手机上做了 ...
- Android 修改屏幕解锁方式
Android 修改屏幕解锁方式 问题 在手机第一次开机的时候,运行手机激活的APP 在激活APP允许过程中,当用户按电源键的时候,屏幕黑掉,进入锁屏状态 手机默认的锁屏是滑动解锁 用户这个时候再一次 ...
- Android] Android XML解析学习——方式比较
[Android] Android XML解析学习——方式比较 (ZT) 分类: 嵌入式 (From:http://blog.csdn.net/ichliebephone/article/deta ...
- Android几种视频播放方式,VideoView、SurfaceView+MediaPlayer、TextureView+MediaPlayer,以及主流视频播放器开源项目
简单的说下一Android的几种视频播放功能: 1.VideoView:最简单的视频播放 <FrameLayout xmlns:android="http://schemas.andr ...
- [转]Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件
Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件. 1.为了防止拖动ListView时,在列表末尾重复数据显示.需要加入 HashMap<In ...
- 理解Android绘制视图的方式
在创建自定义ViewGroup前,读者首先需要理解Android绘制视图的方式.我不会涉及过多细节,但是需要读者理解Android开发文档(见3.5节)中的一段话,这段话解释如何绘制一个布局.内容如下 ...
- Android 查看Apk签名方式V1和V2
Android 查看Apk签名方式V1和V2 java -jar apksigner.jar verify -v my.apk -- Verifies Verified using v1 scheme ...
- Android 进程间通讯方式
Android 进程间通讯方式 1.通过单向数据管道传递数据 管道(使用PipedWriter/ 创建PipedReader)是java.io包的一部分.也就是说,它们是一般的Java功能,而不是An ...
随机推荐
- rsync使用详解
1.什么是Rsync Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.Rsync使用所谓的“Rsync算法”来使本地和远 程两个 ...
- --save-dev和--save的区别
使用npm来进行前端包管理的时候,我们会用到npm install或者cnpm install命令来安装需要用到的包资源 1: npm install *** --save-dev 2: npm in ...
- 5个php实例,细致说明传值与传引用的区别
传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值 说明: 传值 ...
- CF 449D 题解(状压+容斥)
状压妙啊... 本题的主体思路:状压+容斥原理(或状压+数位dp) 记g[i]表示按位与后结果所有位上至少有i个1的方案数 那么根据容斥原理,ans=g[0]-g[1]+g[2]-g[3]+g[4]. ...
- python 全栈开发,Day109(客户管理之动态"二级"菜单)
昨日内容回顾 1. 权限有几张表? 2. 简述权限流程? 3. 为什么要把权限放入session? 4. 静态文件和模块文件 5. 相关技术点 - orm查询 - 去空 - 去重 - 中间件 - in ...
- kafka删除topic数据
一.概述 生产环境中,有一个topic的数据量非常大.这些数据不是非常重要,需要定期清理. 要求:默认保持24小时,某些topic 需要保留2小时或者6小时 二.清除方式 主要有3个: 1. 基于时间 ...
- 向集合中添加Person类型并对其排序
package com.bjpowernode.t03sort; import java.util.ArrayList;import java.util.Collections; /* * 向集合中添 ...
- win10下安装scala
win10安装scala详细步骤 1.下载安装JDK 2.配置Java环境变量 JAVA_HOME:jdk的安装目录 Path:%JAVA_HOME%\bin; Classpath:%JAVA_HOM ...
- BZOJ1293 [SCOI2009]生日礼物 离散化
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1293 题意概括 彩珠有N个,分为K种.每一个彩珠有一个对应的坐标.坐标上可以没有彩珠,多个彩珠也可 ...
- C#介绍
1.c#与.net框架 c#属于.net框架的一个子集. 2..net框架 3.BCL 基类库 4.编译过程 5.运行过程 6.总结 7.CLR