1.Fragment概述

在一个Activity中。 Fragment代表UI的一个部分或者一个行为。一个Activity能够结合多个Fragment对象,也能够在多个activity中使用同样Fragment字节码相应的不同对象。一个Fragment对象必须被嵌入在一个主Activity对象中,该Fragment的生命周期与主Activity息息相关。

比方,当主Activity处于paused状态,其相应的全部Fragment对象均处于paused状态,仅仅有当主Activity处于resumed状态时,Fragment才干处于自由控制状态。

2.创建Fragment

为了创建一个Fragment,应该去继承Fragment或者其子类,覆写对应的方法。比方onCreate(),OnCreateView(),onPause()等等

实例化一个Fragment对象。除了能够new外,还能够使用Fragment的静态函数Fragment.instantiate(mContext, "class 完整路径", info.args);。利用反射实现,可是性能较低

(1).加入UI界面

为该Fragment展现一个布局,必须去实现onCreateView()回掉方法。

注意:当该Fragment继承了ListFragment时。不须要覆写onCreateView()方法,由于默认返回一个ListView对象

[java] view
plain
copy

  1. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  2. Bundle savedInstanceState) {
  3. View view = inflater.inflate(R.layout.list, null);
  4. return view;
  5. }

(2).加入Fragment到Activity

1).通过layout布局文件

android:name属性应该为Fragment相应类的完整路径。

[html] view
plain
copy

  1. <fragment
  2. android:id="@+id/f"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. android:name="com.example.a29fragment.MyFragment"/>

在兼容低版本号时。假设使用静态注冊。而MyFragment是使用了兼容support.v4.app.Fragment,就不能使用Activity了,仅仅能使用FragmentActivity

fragment静态在xml文件配置,该fragment不能被移除,不可动态被编辑。

[html] view
plain
copy

  1. <?

    xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal" >
  6. <fragment
  7. android:id="@+id/list"
  8. android:name="com.example.news.ArticleListFragment"
  9. android:layout_width="0dp"
  10. android:layout_height="match_parent"
  11. android:layout_weight="1" />
  12. <fragment
  13. android:id="@+id/viewer"
  14. android:name="com.example.news.ArticleReaderFragment"
  15. android:layout_width="0dp"
  16. android:layout_height="match_parent"
  17. android:layout_weight="2" />
  18. </LinearLayout>

2).通过Java代码

当Activity执行时,能够自由的在该activity上加入fragment对象。但应该指定一个ViewGroup容器,能够FragmentTransaction完毕fragment的加入移除或者替换。

[java] view
plain
copy

  1. manager = getFragmentManager();
  2. if(manager.findFragmentByTag("right") == null){
  3. manager.beginTransaction().replace(R.id.right, new RightFrag(), "right").commit();
  4. }

(3).fragment唯一标示符

每一个fragment须要定义一个唯一的标识符。假设activity被销毁又又一次启动,系统可以恢复该fragment的状态。

假设想又一次恢复,需满足以下有3种方式之中的一个:

1).定义ID

在布局文件里,定义android:id属性

[html] view
plain
copy

  1. <fragment
  2. android:id="@+id/list"
  3. android:name="com.example.news.ArticleListFragment"
  4. android:layout_width="0dp"
  5. android:layout_height="match_parent"
  6. android:layout_weight="1" />

2).指明tag

android:tag 指明 或者 一个fragment对象add()或者replace()时指定tag

[html] view
plain
copy

  1. <fragment
  2. android:id="@+id/list"
  3. android:tag="first"
  4. android:name="com.example.news.ArticleListFragment"
  5. android:layout_width="0dp"
  6. android:layout_height="match_parent"
  7. android:layout_weight="1" />

或者

[java] view
plain
copy

  1. manager.beginTransaction()
  2. .replace(R.id.right, new RightFrag(), "right")//在事务中指明该fragment的tag
  3. .commit();

3).viewgroup ID

假设该fragment均没有id和tag,系统将使用container view布局的id

3.Fragment的管理

通过getFragmentManager()方法。能够得到FragmentManager对象。主要完毕以下的功能

[java] view
plain
copy

  1. FragmentManager manager = getFragmentManager();

(1).得到已经存在Fragment对象

假设该fragment在布局文件里指定了id。通过findFragmentById()得到对象,或者指定了tag能够通过findFragmentByTag()得到对象

[java] view
plain
copy

  1. Fragment fragment = getFragmentManager().findFragmentByTag("right");
  2. //or
  3. Fragment fragment = getFragmentManager().findFragmentById(id);

(2).注冊OnBackStackChangedListener监听器

能够用来监听该任务相应的返回栈信息。当该返回栈状态发生改变时。运行相应的onBackStackChanged() 方法

[java] view
plain
copy

  1. manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  2. @Override
  3. public void onBackStackChanged() {
  4. Toast.makeText(MainActivity.this, "返回堆状态发生改变", 1).show();
  5. }
  6. });

(3).弹出返回栈

模拟用户点击返回键,将指定的fragment从返回栈中弹出。该操作为异步的。前提是该fragment对象使用.beginTransaction().addToBackStack("right")加入了进返回栈

[java] view
plain
copy

  1. manager.popBackStack(); //Pop the top state off the back stack

(4).FragmentTransaction事务

事务主要包括一些操作的集合,比方添加移除替换。动画设置等等

[html] view
plain
copy

  1. /*
  2. * 通过manager开启一个事务,该事务包括一些操作的集合,通事务能够 add(), remove(), replace()
  3. * 完毕对Fragment的操作,并使用commit()提交
  4. */
  5. FragmentTransaction transaction = manager.beginTransaction();
  6. transaction.replace(R.id.right, new RightFrag(), "right");
  7. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);//设置动画
  8. transaction.addToBackStack("right"); // 将该fragment增加返回堆
  9. // 提交事务
  10. transaction.commit();

(5).Fragment状态管理

[java] view
plain
copy

  1. /*
  2. * 管理Fragment的状态
  3. *  假设在一个主activityViewGroup中加入一个fragment。
  4. *  假设手机屏幕旋转了,当前activity被销毁重建。fragment也被activityManager创建
  5. *  故在onCreate中。须要推断一下
  6. */
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. manager = getFragmentManager();
  12. if (manager.findFragmentByTag("right") == null) {
  13. // if(savedInstanceState == null)也可推断该fragment是否已经载入
  14. manager.beginTransaction()
  15. .replace(R.id.right, new RightFrag(), "right")
  16. .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)// 设置动画
  17. .addToBackStack("right") // 将该fragment增加返回堆
  18. // 提交事务
  19. .commit();
  20. }
  21. }

4.向下兼容

可參阅CursorLoader的兼容~~,特别注意:假设使用静态注冊,在布局文件配置<fragment>标签时,指定了name的class因为兼容support.v4.app.Fragment,载入布局文件的Class就不能继承Activity了,仅仅能继承FragmentActivity

5.Fragment间信息交互

(1).取得对象

[java] view
plain
copy

  1. /*
  2. * 点击该Fragment的button按钮。将该button的text设置为还有一个fragment中Edittext的文本值
  3. */
  4. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  5. Bundle savedInstanceState) {
  6. View view = inflater.inflate(R.layout.list, null);
  7. final Button button = (Button) view.findViewById(R.id.confirm);
  8. button.setOnClickListener(new View.OnClickListener() {
  9. @Override
  10. public void onClick(View v) {
  11. //通过FragmentManager找到还有一个fragment中的edittext对象,并取得text内容
  12. EditText editText = (EditText)(getFragmentManager().findFragmentByTag("left").getView().findViewById(R.id.name));
  13. button.setText(editText.getText().toString());
  14. }
  15. });
  16. return view;
  17. }

(2).通回掉函数

[java] view
plain
copy

  1. public class MainActivity extends Activity {
  2. private FragmentManager manager;
  3. private Button button;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. button.setOnClickListener(new View.OnClickListener() {
  9. @Override
  10. public void onClick(View v) {
  11. RightFragment rightFrag = (RightFragment) (getFragmentManager().findFragmentByTag("right"));
  12. /*
  13. * 通过set方法。向其传递一个实例化对象,因为rightFrag.set()方法内部运行RightFragment.CallBack.get()方法。完毕了參数的传递
  14. */
  15. rightFrag.set(new RightFragment.CallBack() {
  16. @Override
  17. public void get(String str) {
  18. button.setText(str);
  19. }
  20. });
  21. }
  22. });
  23. }
  24. }
[java] view
plain
copy

  1. public class RightFragment extends ListFragment {
  2. private LoaderManager manager;
  3. @Override
  4. public void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. manager = getLoaderManager();
  7. }
  8. /*
  9. * 点击该Fragment的button按钮,将该button的text设置为还有一个fragment中Edittext的文本值
  10. */
  11. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  12. Bundle savedInstanceState) {
  13. View view = inflater.inflate(R.layout.list, null);
  14. return view;
  15. }
  16. /**
  17. * 通过调用该方法,接收一个回掉函数对象,callBack.get(str);
  18. * @param callBack
  19. */
  20. public void set(CallBack callBack) {
  21. EditText editText = (EditText) getView().findViewById(R.id.name);
  22. callBack.get(editText.getText().toString());
  23. }
  24. /*
  25. * 回掉接口
  26. */
  27. interface CallBack {
  28. public void get(String str);
  29. }
  30. }

6.Fragment的生命周期

(1).生命周期路线图

生命状态

周期过程

 

foreground lifetime

onResume(A)

onResume(F)

onPause(F)

onPause(A)

visible lifetime

onCreateView(F)

onActivityCreated(F)

onStart(A)

onStart(F)

onResume(A)

onResume(F)

onPause(F)

onPause(A)

onStop(F)

onStop(A)

onDestroyView(F)

entire lifetime

完整的生命周期

(2).生命周期回掉函数概述

方法 描写叙述
onAttach(Activity)

当前Fragment与Activity关联,调用!

onCreate()

完毕fragment的初始化创建

  onCreateView()

创建并返回与当前fragment相关联的层次视图view

  onActivityCreated()

主activity的onCreate()运行完后。该方法才运行

  onStart()

fragment可见,当主activity处于started状态后运行

    onResume()

fragment能与用户交互。当主activity处于resumed状态后运行

    onPause()

fragment不在与用户交互,可能在主activity将要处于paused前运行,可能该fragment被改动

  onStop()

fragment不在可见,可能在主activity将要处于stopped前运行,可能该fragment被改动

  onDestroyView()

同意该fragment清理视图相关资源

onDestroy()

清理掉视图state信息

onDetach()

该fragment不在于activity关联



经验解决Fragment 被 Replace后仍旧可见的问题

网上问的问题,大多会提到替换了Fragment而发现之前被替换的仍旧显示在那里。我个人使用android
2.3 +support 开发包。在2.3系统上也出现类似问题。搜了下网上的问题,好像都没有找到解决方法。之后自己摸索。

最后发现事实上。对于Fragment的替换 JAVA代码基本上没啥,网上都是正确的,比方:

  1. FragmentManager fragmentManager = getSupportFragmentManager();
  2. FragmentTransaction transaction = fragmentManager.beginTransaction();
  3. OrderFragment orderFragment = new OrderFragment();
  4. Bundle args = new Bundle();
  5. args.putInt("card_id", LoginHelper.currentCard.getId());
  6. args.putBoolean("create_order", true);
  7. orderFragment.setArguments(args);
  8. transaction.replace(R.id.layout_shopping1, orderFragment);
  9. //transaction.addToBackStack(null);
  10. transaction.commit();

复制代码

但多数人并没有意识到,贴出 XML布局文件的重要性:

正确的做法是必须使用FrameLayout作为Fragment被替换的布局容器

比如:

  1. <?xml version="1.0" encoding="utf-8"?

    >

  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/layout_shopping1"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:background="@color/black" >
  7. </FrameLayout>

复制代码

不可以使用比方线性布局LinearLayout 等。否则就会发生看得见的问题。

奉献点经验,期望能够帮助到遇到类似问题的开发人员。











版权声明:本文博客原创文章。博客,未经同意,不得转载。

Android Fragment——详细解释的更多相关文章

  1. Android slidingmenu详细解释 滑动的优化

    Android slidingmenu 详细解释 性能优化 转载请注明:   http://blog.csdn.net/aaawqqq 简单介绍 SlidingMenu 是github 上Androi ...

  2. Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点

    android 应用.准则欢迎页面. 和图像旋转木马特征, 或者没有很多其他的内容显示在一个页面.以被划分成多个页面,在这一刻viewpager这是非常容易使用. 首先看下效果: 以下是一个样例.带异 ...

  3. Android中时间戳的详细解释

    Android中时间戳的详细解释: (1).定义: 时间戳就是根据当前系统时间生成的一组随机数字. (2).作用: 作为对数据唯一性的一种判断依据.避免了重复修改数据所带来的错误! (3).应用: ( ...

  4. Android Fragment碎片

    什么是碎片? 碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛.可以把Fragment当成Activity一个界面的一 ...

  5. Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复

    Android中的状态保存和恢复 Android中的状态保存和恢复, 包括Activity和Fragment以及其中View的状态处理. Activity的状态除了其中的View和Fragment的状 ...

  6. Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误

    嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...

  7. Android Fragment应用实战

    现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ...

  8. Android Fragment

    1.Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期. 2.Fragment 生命周期: 首页 最新文章 在线课程 业界 开发 ...

  9. Android Fragment应用实战,使用碎片向ActivityGroup说再见

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/13171191 现在Fragment的应用真的是越来越广泛了,之前Android在3 ...

随机推荐

  1. 那些移动端web踩过的坑

    原文链接:https://geniuspeng.github.io/2017/08/24/mobile-issues/ 扔了N久,还是捡回来了.好好弄一下吧.刚工作的时候挺忙的,后来不那么忙了,但是变 ...

  2. 解决maven项目找不到maven依赖的解决办法

    不同的IDE对应的.classpath中的maven声明也不一样,这样就会导致项目找不到maven依赖. 即Java Build Path--->Libraries中找不到Maven Depen ...

  3. 【PHP】php 递归、效率和分析(转)

    递归的定义 递归(http:/en.wikipedia.org/wiki/Recursive)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...

  4. 2016.3.14__CSS 定位__第六天

    假设您认为这篇文章还不错.能够去H5专题介绍中查看很多其它相关文章. CSS 定位机制 CSS中一共同拥有三种基本定位机制:普通流.浮动.绝对定位. 假设不进行专门指定.全部的标签都在普通流中定位. ...

  5. .gitignore 设置忽略上传的文件

    首先在一个项目中新建如下所示文件用来测试 image.png 一.生成.gitignore文件 1.进入项目根目录,打开终端: 2.输入 vi .gitignore 创建并打开隐藏文件.gitigno ...

  6. kindeditor4跨域上传图片解决

    项目中正在使用kindeditor, 版本号4.1.10 非常多公司的图片会走CDN,须要单独的一台图片上传服务如:(upload.268xue.com) kindeditor上传图片的简单内部流程: ...

  7. Jquery前端分页插件pagination同步加载和异步加载

    上一篇文章介绍了Jquery前端分页插件pagination的基本使用方法和使用案例,大致原理就是一次性加载所有的数据再分页.https://www.jianshu.com/p/a1b8b1db025 ...

  8. 灵活使用Excel可能会提高Java代码编写效率

    使用Java操作数据时,当表字段太多时,书写实体类和进行实体类对象操作时都是一个繁重且易错的工作,光靠复制粘贴快捷键已不能满足负责的操作. 首先,说一下,就是在Eclipse中的快捷键,小写:ctrl ...

  9. 【codeforces 777C】 Alyona and Spreadsheet

    [题目链接]:http://codeforces.com/contest/777/problem/C [题意] 给你n行m列的矩阵: 然后给你k个询问[l,r]; 问你在第l到第r行,是否存在一个列, ...

  10. js中多层复杂并且动态键值JSON的获取方法

    开发中遇到了用js解析重新组装json数据的要求,关键点在于JSON中的串的键是动态的,多方查找解决了在此做个记录.同时我也深感js中循环的无赖,如果用i作为键会得到索引,用key作为循环变量竟然可以 ...