为了在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. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  2. [LeetCode] Letter Combinations of a Phone Number 电话号码的字母组合

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  3. ping环回地址和ping主机地址的区别

    ping127.0.0.1和ping本机的过程是不一样的ip输出函数先检查地址是不是环回地址1.如果是环回地址 直接交给环回驱动程序处理 返回ip输入函数2.如果不是环回地址 检查是不是广播或者多播地 ...

  4. 用vue.js学习es6(五):set和map的使用

    一:Set用法: ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. (1).打印:console.log var data = new Set([1,2,3]); ...

  5. 在 kernel 下打 log。 怪異現象與解決方式。

    code battery_log(BAT_LOG_CRTI, "y t: %d \n", (int)my_timer_timeout); battery_log(BAT_LOG_C ...

  6. CephRGW 在多个RGW负载均衡场景下,RGW 大文件并发分片上传功能验证

    http://docs.ceph.com/docs/master/radosgw/s3/objectops/#initiate-multi-part-upload 根据分片上传的API描述,因为对同一 ...

  7. UIButton快速点击,只执行最后一次

    button快速点击时,会导致,同一动作执行多次,常用解决办法: 第一种方法:推荐 //取消执行 [[self class] cancelPreviousPerformRequestsWithTarg ...

  8. ABP 索引

    官方网站 Github ABP集合贴 @ kebinet https://www.codeproject.com/articles/1115763/using-asp-net-core-entity- ...

  9. C#-WebForm-文件上传-FileUpload控件

    FileUpload - 选择文件,不能执行上传功能,通过点击按钮实现上传 默认选择类型为所有类型 //<上传>按钮 void Button1_Click(object sender, E ...

  10. 【总结】.Net面试题集锦 (二)

    一.前面的话 本文的面试题不是很难,这里只是想记录个人的思考过程,另一方面希望有更好的解决办法的大牛留下宝贵的思路,大家共同学习进步. 二.题目 思路:第一步:把一维数组的值和次数存入Dictiona ...