android——Fragment
谷歌官方文档的介绍:
https://developer.android.com/guide/components/fragments.html#Design
Fragment
表示 Activity
中的行为或用户界面部分。您可以将多个片段组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个片段。您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段(有点像您可以在不同 Activity 中重复使用的“子 Activity”)。
片段必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。 例如,当 Activity 暂停时,其中的所有片段也会暂停;当 Activity 被销毁时,所有片段也会被销毁。 不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您可以独立操纵每个片段,如添加或移除它们。 当您执行此类片段事务时,您也可以将其添加到由 Activity 管理的返回栈 — Activity 中的每个返回栈条目都是一条已发生片段事务的记录。 返回栈让用户可以通过按返回按钮撤消片段事务(后退)。
当您将片段作为 Activity 布局的一部分添加时,它存在于 Activity 视图层次结构的某个 ViewGroup
内部,并且片段会定义其自己的视图布局。您可以通过在 Activity 的布局文件中声明片段,将其作为 <fragment>
元素插入您的 Activity 布局中,或者通过将其添加到某个现有 ViewGroup
,利用应用代码进行插入。不过,片段并非必须成为 Activity 布局的一部分;您还可以将没有自己 UI 的片段用作 Activity 的不可见工作线程。
一、使用Fragment的两种方式
1、在Activity的布局中加入fragment
这种方式就是在Activity的布局中把fragment当作一个控件来使用,不过这等于是将视图和Activity的视图绑在一起,在Activity的生命周期内无法切换fragment。
先新建一个继承Fragment的类,重写onCreateView决定Fragemnt的布局,onCreateView里面还需要一个布局文件,右键layout→new→file 创建一个fragment.xml的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/crime_tittle_hint"/> </LinearLayout>
这个布局是怎样,是无所谓的,只根据需求来编写即可。
然后在继承Fragment的类里,重写onCreateView将这个加载这个布局
public class Fragment1 extends Fragment { @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
return view;
}
}
调用LayoutInflater的inglate()方法加载布局,第一个参数是布局资源的ID,第二个参数是视图的父视图。
然后在活动的布局文件中在Activity中使用这个Fragment,就当和普通的View一样
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <fragment
android:id="@+id/id_fragment_content"
android:name="xbt.exp22.Fragment1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /> </RelativeLayout>
2、在Activity的代码中加入fragment
这种可以在运行时控制fragment可以自行决定加载那一个fragment,也可以移除,换一个fragment
修改活动的布局,把之前的碎片view删掉,加入一个按钮和一个FrameLayout,给FrameLayout设置一个ID
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <FrameLayout
android:id="@+id/fragment"
android:layout_below="@id/button1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /> </RelativeLayout>
修改活动的代码:
public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1= (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.FrameLayout,new Fragment1());
transaction.commit();
}
});
}
}
按钮响应的内容是:使用getFragmentManager();获取FragmentManager,使用beginTransaction();开启一个事务transaction,然后向容器添加或替换片段,需要传入容器的id和片段,然后使用commit()提交事务。其中FragmentTransaction()的replace方法第一个参数是想要放片段的布局的id,第二个参数就是想要放入的片段的一个对象。这样就能实现点击按钮之后片段才出现。
这里的添加碎片fragment还可以这样写:
public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1= (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.FrameLayout,new Fragment1())
.commit();
}
});
}
}
总的来说过程其实大体都是一样的,
1、Activity使用FragmentManager来管理fragment队列,
2、FragmentManager调用beginTransation()创建一个FragmentTransaction(),
3、调用add()或replace()告诉FragmentManager,fragment视图应该出现在activity视图的那个位置,使用那一个fragment。
4、最后提交事务调用commit()
二、将一个片段替换成另一个片段:
需要新建一个fragment类和它的布局:
fragment类Fragment2.class:
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
return view;
}
}
布局:fragment2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第二个片段"/> </LinearLayout>
活动的java代码:
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.FrameLayout,new Fragment2())
.addToBackStack(null)
.commit();
}
});
新的Fragment替换在 R.id.fragment_container
ID 所标识的布局容器中的任何片段(如有),通过调用 addToBackStack()
可将替换事务保存到返回栈,以便用户能够通过按返回按钮撤消事务并回退到上一片段。
如果您向事务添加了多个更改(如又一个 add()
或 remove()
),并且调用了 addToBackStack()
,则在调用 commit()
前应用的所有更改都将作为单一事务添加到返回栈,并且返回按钮会将它们一并撤消。
向 FragmentTransaction
添加多个更改的顺序无关紧要,不过:
- 必须最后调用
commit()
- 如果要向同一容器添加多个片段,则您添加片段的顺序将决定它们在视图层次结构中的出现顺序
如果没有在执行移除片段的事务时调用 addToBackStack()
,则事务提交时该片段会被销毁,用户将无法回退到该片段。 不过,如果您在删除片段时调用了 addToBackStack()
,则系统会停止该片段,并在用户回退时将其恢复。
二、fragment的生命周期
图片.Activity 生命周期对片段生命周期的影响
片段生命周期与管理 Activity 生命周期很相似。和 Activity 一样,片段也以三种状态存在:
Resumed
片段在运行中的 Activity 中可见。
Paused
另一个 Activity 位于前台并具有焦点,但此片段所在的 Activity 仍然可见(前台 Activity 部分透明,或未覆盖整个屏幕)。
Stoped
片段不可见。宿主 Activity 已停止,或片段已从 Activity 中移除,但已添加到返回栈。 停止片段仍然处于活动状态(系统会保留所有状态和成员信息)。 不过,它对用户不再可见,如果 Activity 被终止,它也会被终止。
和Activity 一样,假使 Activity 的进程被终止,在重建 Activity 时需要恢复片段状态,也可以使用 Bundle
保留片段的状态。可以在片段的 onSaveInstanceState()
回调期间保存状态,并可在 onCreate()
、onCreateView()
或 onActivityCreated()
期间恢复状态。
Activity 生命周期与片段生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。 默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈(也就是打开另一个活动之后当前活动就会处于停止状态,点击返回按钮后就会自动恢复)。不过,但是如果在执行移除片段的事务执行期间不通过调用 addToBackStack()
显式请求保存实例时,系统不会将片段放入由宿主 Activity 管理的返回栈,也就是说按返回就不会恢复。
一个例子:新建一个拥有一个按钮的SecondActivity,这个按钮的响应是使用Intent启动一个MainActivity, 将MainActivity中的两个按钮的响应修改为启动一个SecondActivity和销毁本活动,在MainActivity中静态加载一个片段,在该片段中将器生命周期内的每一个方法都重写输出日志方法名字
活动的java代码:
public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
}); Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
Log.d("message","MainActivity:onCreate");
} @Override
protected void onStart() {
super.onStart();
Log.d("message","MainActivity:onStart");
} @Override
protected void onResume() {
super.onResume();
Log.d("message","MainActivity:onResume");
} @Override
protected void onPause() {
super.onPause();
Log.d("message","MainActivity:onPause");
} @Override
protected void onStop() {
super.onStop();
Log.d("message","MainActivity:onStop");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d("message","MainActivity:onDestroy");
}
}
片段的java代码:
public class Fragment1 extends Fragment { @Override
public void onAttach(Context context) {
super.onAttach(context);
Log.d("message","Fragment1:onAttach");
} @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("message","Fragment1:onCreate");
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
Log.d("message","Fragment1:onCreateView");
return view;
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("message","Fragment1:onActivityCreated");
} @Override
public void onStart() {
super.onStart();
Log.d("message","Fragment1:onStart");
} @Override
public void onResume() {
super.onResume();
Log.d("message","Fragment1:onResume");
} @Override
public void onPause() {
super.onPause();
Log.d("message","Fragment1:onPause");
} @Override
public void onStop() {
super.onStop();
Log.d("message","Fragment1:onStop");
} @Override
public void onDestroyView() {
super.onDestroyView();
Log.d("message","Fragment1:onDestroyView");
} @Override
public void onDestroy() {
super.onDestroy();
Log.d("message","Fragment1:onDestroy"); } @Override
public void onDetach() {
super.onDetach();
Log.d("message","Fragment1:onDetach");
}
}
刚启动应用程序时:
启动SecondActivity:
在SecondActivity启动一个MainActivity:
点击返回到SecondActivity
再点击返回
点击第二个按钮销毁活动
以上就是片段跟随活动的生命周期状态变化自身状态随之变化并调用相应方法的验证。
android——Fragment的更多相关文章
- 【Android自学日记】【转】Android Fragment 真正的完全解析(下)
上篇博客中已经介绍了Fragment产生原因,以及一些基本的用法和各种API,如果你还不了解,请看:Android Fragment 真正的完全解析(上). 本篇将介绍上篇博客提到的:如何管理Frag ...
- Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
Toolbar作为ActionBar使用介绍 本文介绍了在Android中将Toolbar作为ActionBar使用的方法. 并且介绍了在Fragment和嵌套Fragment中使用Toolbar作为 ...
- Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复
Android中的状态保存和恢复 Android中的状态保存和恢复, 包括Activity和Fragment以及其中View的状态处理. Activity的状态除了其中的View和Fragment的状 ...
- Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...
- Android Fragment使用(一) 基础篇 温故知新
Fragment使用的基本知识点总结, 包括Fragment的添加, 参数传递和通信, 生命周期和各种操作. Fragment使用基础 Fragment添加 方法一: 布局里的标签 标识符: tag, ...
- Android Fragment应用实战
现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ...
- Android Fragment 真正的完全解析(下)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 上篇博客中已经介绍了Fragment产生原因,以及一些基本的用法和 ...
- Android Fragment
1.Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期. 2.Fragment 生命周期: 首页 最新文章 在线课程 业界 开发 ...
- Android Fragment应用实战,使用碎片向ActivityGroup说再见
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/13171191 现在Fragment的应用真的是越来越广泛了,之前Android在3 ...
- Android Fragment完全解析
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8881711 我们都知道,Android上的界面展示都是通过Activity实现的, ...
随机推荐
- c++最大公约数
C++辗转相除法求出最大公因数 样例输入 6 9 样例输出 3 程序 #include <stdio.h> using namespace std; int gcd(int m,int n ...
- Redis复制流程:图解
一.新版复制PSYNC命令实现:复制实现总流程 (1)通过客户端向从服务器发送 slaveof <master_ip> <master_port>:此为异步执行,从服务器设置好 ...
- IDM 6.27.5(Internet Download Manager)中文破解版下载神器
IDM一直是我最喜欢的下载工具,感觉用的比迅雷爽,简单使用,对付网盘有一套.IDM(Internet Download Manager)和迅雷的下载提速方式不同,从原理上来说,IDM速度较稳定,迅雷下 ...
- 自定义HashSet判重标准
HashSet在执行add时会首先根据目标类的hashcode判断是否有与其hashcode相同的对象,若有则使用equals该对象判断是否与其相同. HashSet保证了元素的唯一性, 我们可以通过 ...
- [记录]优化Linux 的内核参数来提高服务器并发处理能力
优化Linux 的内核参数来提高服务器并发处理能力PS:在服务器硬件资源额定有限的情况下,最大的压榨服务器的性能,提高服务器的并发处理能力,是很多运维技术人员思考的问题.要提高Linux 系统下的负载 ...
- UVA816 Abbott的复仇 Abbott's Revenge
以此纪念一道用四天时间完结的题 敲了好几次代码的出错点:(以下均为正确做法) memset初始化 真正的出发位置必须找出. 转换东西南北的数组要从0开始. bfs没有初始化第一个d 是否到达要在刚刚取 ...
- 6.1.初识Flutter应用之实现一个计数器
用Android Studio和VS Code创建的Flutter应用模板是一个简单的计数器示例,本节先仔细讲解一下这个计数器Demo的源码,让读者对Flutter应用程序结构有个基本了解,在随后小节 ...
- Excel催化剂开源第34波-SM.MS图床API调用(用POST上传multipart/form-data内容)
日常做网抓数据,都是以GET请求为主,偶尔遇到需要POST请求的,一般POST的参数只是一串字符串就可以了,通过构造字符串也很容易完成,但此次SM.MS的API接口要求是Content-Type: m ...
- 个人永久性免费-Excel催化剂功能第99波-手机号码归属地批量查询
高潮过往趋于平静,送上简单的手机号码归属地查询,因接口有数量限制,仅能满足少量数据需求,如有大规模数据却又想免费获得,这就成为无解了,数据有价,且用且珍惜. 业务使用场景 除了日常自带的手机各种管家为 ...
- 个人永久性免费-Excel催化剂功能第39波-DotNet版的正则处理函数
在很久之前已经开发过的一些自定义函数,未能有详细的讲解,接下来几波中着重对之前开发过的自定义函数进行详细讲解及示例说明,希望能够帮助到普通用户们能顺利使用,此篇介绍为正则表达式函数. 文章出处说明 原 ...