为了在Activity布局文件中使用Fragment我们需要四个步骤。

1.定义一个Activity,他继承android.support.v4.app.FragmentActivity,下面是关键代码

import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

	@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

2.定义Activity的布局文件activity_main.xml,注意fragment是小写的,且name属性的值必须是完全限定包名

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <fragment
android:name="com.example.v4fragmenttest.MyFragment"
android:id="@+id/myfragmentid"
android:layout_width="400px"
android:layout_height="500px"
android:layout_gravity="center"
/> </LinearLayout>

3.自定义一个Fragment,他继承android.support.v4.app.Fragment,关键代码如下

import android.support.v4.app.Fragment;

public class MyFragment extends Fragment {

	@Override
@Nullable
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//System.out.println("Fragment onCreateView");
//System.out.println(container == null);
return inflater.inflate(R.layout.fragment, container, false);
} }

4.定义Fragment对应的布局文件fragment.xml(名字任意),fragment.xml和普通的布局文件是完全一样的

 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="这是Fragment的TextView,他是水平居中的" />

完整的源码下载:点我下载


可以发现在布局文件中使用自定义view和和fragment是有些类似的,但是有些区别

1.自定义view在布局文件中定义是<com.xxnote.myview />,Fragment则是<fragment  android:name="com.example.v4fragmenttest.MyFragment" />的形式

2.自定义view要继承view,而自定义Fragment需要继承android.support.v4.app.Fragment

同时也可以发现,自定义的Fragment本质就是一个继承了android.support.v4.app.Fragment的类,在他的onCreateView里面返回一个View,这个View会替换掉Activity布局文件里面的fragment标签

另外SDK文档中有这么一句话

Note: Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). There are three ways to provide an ID for a fragment:

  • Supply the android:id attribute with a unique ID.
  • Supply the android:tag attribute with a unique string.
  • If you provide neither of the previous two, the system uses the ID of the container view.

可见每一个Fragment都需要一个unique identifier,有三种方式可以为他提供unique identifier,

第一种是使用Fragment的android:id属性作为unique identifier,如下:

 <fragment
android:name="com.example.v4fragmenttest.MyFragment"
android:id="@+id/myfragmentid"
android:layout_width="400px"
android:layout_height="500px"
android:layout_gravity="center"
/>

第二种是使用Fragment的android:tag属性作为unique identifier

<fragment
android:name="com.example.v4fragmenttest.MyFragment"
android:tag="myfragmenttag"
android:layout_width="400px"
android:layout_height="500px"
android:layout_gravity="center"
/>

第三种是如果上面两种都没提供,系统会使用父容器的id作为unique identifier,如下

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myactivitylayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <fragment
android:name="com.example.v4fragmenttest.MyFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/> </LinearLayout>

上面的Fragment的unique identifier就是父容器的id,可以使用getSupportFragmentManager().findFragmentById(R.id.layoutfragment)来获取这个Fragment。

但是试了下发现上面三种方式都没提供的话也没什么影响,这个应该是用代码添加Fragment的时候才会用到,在布局文件中使用Fragment没啥用,以后再好好研究下

下午研究了下,终于搞清楚unique identifier了,unique identifier的作用就是用来传给FragmentManager的findFragmentByTag或者findFragmentById这两个方法的,这两个方法根据唯一的unique identifier来确定到底是要查找那个Fragment,那么问题来了,如果这些Fragment的unique identifier相同会出现什么情况呢?这时通过这个unique identifier查找到的Fragment是用这个unique identifier设置的最后一个Fragment,即使这个Fragment被remove了,再用这个unique identifier来查找Fragment也无法查找到其他的Fragment,只会返回null。

什么情况下会出现unique identifier相同的情形呢?一种情况是同一个布局中有多个使用父容器的id作为unique identifier的Fragment,即上面的为Fragment分配unique identifier的第三种方式,第二种情况就是通过代码添加Fragment,如下:

 fragmentTransaction.add(R.id.myactivitylayout, new MyFragment(), "000");

第三种情况就是第一种和第二种情况的结合了。

通过代码添加Fragment的时候第一个参数必须是父容器的id,即上面的R.id.myactivitylayout,所以这些添加的Fragment都会有相同的unique identifier,因此我们会无法查找所有的Fragment,这时第三个参数派上了用场, fragmentTransaction.add(R.id.myactivitylayout, new MyFragment(), "000"); 这句里面的第三个参数"000"也会作为Fragment的unique identifier,查找的时候使用FragmentManage的findFragmentByTag方法就可以了。因此最好不要使用FragmentManager的findFragmentById方法来查找Fragment,而是使用FragmentManage的findFragmentByTag方法来查找Fragment。

还有一些要注意的地方就是在布局xml里面的fragment是无法删除和replace的;对于一个fragmentTransaction只能调用一次commit()方法,再进行add、remove、replace后必须commit才生效,如果一个fragmentTransaction已经commit过一次了,那么再要进行add、remove、replace的时候就调用getSupportFragmentManager().beginTransaction()方法重新获得一个fragmentTransaction,然后使用这个fragmentTransaction来add、remove、replace我们的Fragment,最后了commit一下就生效了;commit是异步的,因此当我们commit之后立刻查找Fragment很可能会返回null。

在布局文件中使用Fragment的步骤的更多相关文章

  1. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  2. Android 自定义View及其在布局文件中的使用示例

    前言: 尽管Android已经为我们提供了一套丰富的控件,如:Button,ImageView,TextView,EditText等众多控件,但是,有时候在项目开发过程中,还是需要开发者自定义一些需要 ...

  3. Android 自定义View及其在布局文件中的使用示例(二)

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...

  4. Android中布局文件中使用onClick属性

    安卓开发中,布局文件中的控件有一个属性,是onClick,例如:           <Button             android:id="@+id/button1" ...

  5. android 布局文件中xmlns:android="http://schemas.android.com/apk/res/android"

    http://blog.163.com/benben_long/blog/static/199458243201411394624170/ xmlns:android="http://sch ...

  6. Android查缺补漏(View篇)--布局文件中的“@+id”和“@id”有什么区别?

    Android布局文件中的"@+id"和"@id"有什么区别? +id表示为控件指定一个id(新增一个id),如: <cn.codingblock.vie ...

  7. ASP.NET MVC 4 (十一) Bundles和显示模式--asp.net mvc中 @Scripts.Render("~/bundles/jquery")是什么意思? 在布局文件中使用Scripts.Render()输出脚本包,Styles.Render()输出风格包:

    ASP.NET MVC 4 (十一) Bundles和显示模式 ASP.NET MVC 4 引入的js打包压缩功能.打包压缩jquery目录下的文件,在布局文件中使用Scripts.Render()输 ...

  8. 安卓---achartengine图表----简单调用----使用view显示在自己的布局文件中----actionBar的简单设置

    AChartEngine 是一个安卓系统上制作图表的框架,关于它的介绍大家可以百度,也可以参考下面这篇博客http://blog.csdn.net/lk_blog/article/details/76 ...

  9. Android中查看布局文件中的控件(view,id)在哪里被调用(使用)

    在阅读别人的代码时通常是很痛苦的,有时很想要看一看布局中的控件在哪里被调用了,为之很苦恼 在这里提供一种方法.   复制要查看的控件ID,到R文件中搜索到该ID,   接下来就好办的了,选中ID按下C ...

随机推荐

  1. appscan 对api的手工检测

    AppScan 在 API 安全测试中的实例介绍 在本项目中,API 遵循标准的的 REST 架构和背端服务器进行通信.针对 API 的功能测试由两部分组成:一部分是用一个 Web 的测试页面直接实现 ...

  2. 基于GPU的高分一号影像正射校正的设计与实现

    一 RPC正射校正的原理 影像正射校正的方法有很多,主要包含两大类:一类是严格的几何纠正模型,另一类是近似几何纠正模型.当遥感影像的成像模型和有关参数已知时,可以根据严格的成像模型来校正图像,这种方法 ...

  3. [LeetCode] Remove Linked List Elements 移除链表元素

    Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...

  4. [LeetCode] One Edit Distance 一个编辑距离

    Given two strings S and T, determine if they are both one edit distance apart. 这道题是之前那道Edit Distance ...

  5. [LeetCode] Path Sum 二叉树的路径和

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...

  6. Bootstap datetimepicker报错TypeError: intermediate value

    Bootstrap datetimepicker有多个版本,官方的链接中,只是datepicker,没有时间的选择,原版的datetimepicker也不再更新,不能用新版的jquery.现在http ...

  7. MessageDialog

    var messageDialog = new Windows.UI.Popups.MessageDialog("Media player components unavailable&qu ...

  8. 使用Mysql Workbench 画E-R图

    MySQL Workbench 是一款专为MySQL设计的ER/数据库建模工具.你可以用MySQL Workbench设计和创建新的数据库图示,建立数据库文档,以及进行复杂的MySQL 迁移.这里介绍 ...

  9. Mysql多表表关联查询 inner Join left join right join

    Mysql多表表关联查询 inner Join left join right join

  10. Jackson 通过自定义注解来控制json key的格式

    Jackson 通过自定义注解来控制json key的格式 最近我这边有一个需求就是需要把Bean中的某一些特殊字段的值进行替换.而这个替换过程是需要依赖一个第三方的dubbo服务的.为了使得这个转换 ...