Android — 创建和修改 Fragment 的方法及相关注意事项
如何创建 fragment activity
public class FooFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {// 为fragment提供 XML 布局文件return inflater.inflate(R.layout.fragment_foo, container, false);}
}
如何在代码中使用 Fragment
在代码中实现 Fragment 一般有两种方法,分别为静态实现和动态实现。
1. 在 XML 中确定 Fragment 内容
在 XML 通过 android:name
参数来确定 fragment 要显示的内容,这种方法建立的 fragment 不可以在程序运行过程中移除,示例代码如下:
<fragmentandroid:name="com.fragment.FooFragment"tools:layout="@layout/fragment_foo"android:id="@+id/fragment"android:layout_width="match_parent"android:layout_height="wrap_content" />
其中的 com.fragment.FooFragment
为名为 FooFragment 的 Fragment Activity。
2. 在程序运行时确定 Fragment 内容
首先,在 xml 布局文件中应该放置 FragmentLayout 作为 fragment 的容器,代码如下:
<FrameLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/fragment_container">
</FrameLayout>
在声明了 android:id
之后,在 Java 代码中就可以操作这个 Fragment 容器了。可以使用add()
, replace()
, remove()
等方法,示例代码如下:
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.remove(R.id.fragment_container, new FooFragment());
fragmentTransaction.commit();
3. add() 方法和 replace() 方法说明
add()
方法是在原有的基础上添加一个 fragment,实现叠加的效果。
replace()
方法是将原先所有的 fragment 移除,然后添加一个 fragment。
如何保留 Fragment 状态
不要每次都 new 一个 Fragment,而是用 hide()
和 show()
方法来实现切换。
在 onCreate()
中先 add()
两个 fragment。
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.fragment_container, homeFragment);
fragmentTransaction.add(R.id.fragment_container, meFragment);
fragmentTransaction.commit();
之后需要切换时,用如下方法实现。
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.hide(meFragment);
fragmentTransaction.show(homeFragment);
fragmentTransaction.commit();
关于 fragment 的注意事项
1. 如何理解 addToBackStack() 方法
fragmentTransaction.replace(R.id.fragment_container, new BarFragment());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
在代码中,我们可以看到,addToBackStack()
方法作用的对象是一个 transaction。也就是说,在执行这个 transaction 时,系统会建立一个回退栈,其中记录的是进行 transaction 前后 fragment 的内容。当手机上的 back 键按下时,最后建立的回退栈先进行响应,使得当前 fragment 先 remove 进行 transaction 后 fragment 的内容,再 add 上进行 transaction 前 fragment 的内容。
来一个实例,假设当前 fragment 内容为 C,先进行了一次有 addToBackStack 的replace(container, A)
,再进行一次无 addToBackStack 的replace(container, B)
时,如果触发了 back 事件,那么之前建立的回退栈响应,使 fragment 先 remove 掉 A,事实上本来就已经没了有,然后 add 上原先状态的C。此时,B是不会被 remove 掉的。所以,最后 fragment 中的内容为 B 和 C 两者的叠加。
如果希望清空 fragment 的回退栈,可以采用在 replace 前加上 popBackStack()
方法,第二个参数为POP_BACK_STACK_INCLUSIVE。示例代码如下:
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, new FooFragment());
fragmentTransaction.commit();
2. 关于 fragmentTransaction 的延迟问题
fragmentTransaction.commit()
并不是立即执行的,也并非进入UI线程队列中等待顺序执行,而是由系统自动调配,在 UI 线程空闲时执行。这样就会产生一个问题,如果我需要获取到 fragment 中对象的实例,这个时候findViewById()
方法会返回 null ,那么如何解决这个问题呢?
第一种方法是通过getSupportFragmentManager().executePendingTransactions()
来让 transaction 立即加入UI线程执行,而不是被调配在空闲时间执行。但是如果是在其他线程中获取view,这个方法依然行不通,因为有可能UI线程本身正在进行一个相对耗时的操作,而第二种方法则更为安全。
第二种方法是在 fragment activity 的onCreateView()
方法中获取对应的view,示例代码如下:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment_bar, container, false);textView = (TextView)rootView.findViewById(R.id.textbar); return rootView;
}
fragment lifecycle 流程图
references:
Building a Dynamic UI with Fragments
Building a Flexible UI
Fragments API Guides
Android — 创建和修改 Fragment 的方法及相关注意事项相关推荐
- android保存连接地址到桌面快捷方式,Android创建桌面快捷方式两种方法
谈谈在桌面上直接生成.个人觉得这个比较爽快,既然都是快捷方式了干嘛还要再隐藏一层呢?当然喜欢桌面干净的就比较喜欢第二个了. 第一个是通过广播(Broadcast)的形式向Luncher发送请求生成快捷 ...
- SQL语句创建、修改视图的方法
根据实验1-3中创建的学生作业管理数据库以及其中的学生表.课程表和学生作业表,进行以下操作(见前面文章). 1.创建一个电子05的学生视图(包括学号.姓名.性别.专业班级.出生日期). 2.创建一个生 ...
- Android 泽宇管理Fragment的方法
public Fragment addFragment(int id, Class<Fragment> fragmentClass, Map<String,String> ma ...
- FreeBasic写DLL给VB6调用(直接用API创建和修改VB字符串方法)
写DLL给VB用,不是什么难题,但我们要做到字符变量,从FreeBasic到VB6,从VB6到FreeBasic,在VB6端无痛使用,那就要费点功夫了. VB6代码:直接写 String Privat ...
- android 动态更改主题,Android应用动态修改主题的方法示例
1.使用API设置主题 如下所示,在Activity中使用setTheme setTheme(R.style.MyTheme1); 2.调用API的时机 需要在super.onCreate(saved ...
- 并联串联混合的电压和电流_图文详解:电流互感器的接线方法及相关注意事项!还不收藏?...
我们从使用功能上将电流互感器分为测量用电流互感器和保护用电流互感器两类,各种电流互感器的原理类似,本文总结了一些电流互感器知识,供参考使用. 一.电流互感器铭牌 电流互感器型号由以下几部分组成,各部分 ...
- android onattach方法,Java Fragment.onAttach方法代码示例
import android.support.v4.app.Fragment; //导入方法依赖的package包/类 private void testBindToLifecycle(Lifecyc ...
- android编辑配置文件,如何在android studio中修改配置文件
在使用android studio过程中,你知道怎么手动修改配置文件吗?下面是学习啦小编给大家整理的一些有关在android studio中修改配置文件的方法,希望对大家有帮助! 在android s ...
- linux 批量更换文件名,Linux下批量修改文件名的方法
Linux下批量修改文件名的方法 在Linux环境下修改文件名可以有不同的命令方式,比如rename.mv都可以进行修改,如果用户正在了解这方面的知识,可以阅读下文了解Linux修改文件名以及批量修改 ...
最新文章
- 来淄博旅游_JAVA
- boost::log::filter用法的测试程序
- java正则 环视_正则表达式之环视(java)
- Posix本地通信用于同一设备或native和framework层之间
- 自己实现一个SQL解析引擎
- vue 拖拽产生连线_连接两个div的直线,拖动时保持连线。
- 游戏手柄延迟测试软件,六款免费网络延迟测试工具
- 画图工具的认识及应用计算机,认知画图软件教学设计
- 数据结构与算法(三):链表
- dockerfile
- java ftp 卡死_ftpclient卡死问题
- 北航计算机专业怎么样考研好考不,计算机专业考研,北航和北邮各有什么优势...
- 自动化测试应用---HTML测试报告+邮件发送
- Window系统电脑登录过个微信方法,微信多开(实测)
- ecb里使用自定义快捷键切换窗口
- EternalBlue复现过程
- 菜鸟Python实战-03爬虫之爬取数据
- matlab用diag直接使用错误_Matlab diag的用法
- 好用的企业邮箱服务都有哪些好处
- 小米手环3nfc和4nfc哪个好_重度使用小米手环4NFC版3个月后,聊聊优缺点