碎片
1.碎片是什么
Fragment是Android3.0后引入的一个新的API,它出现的初衷是为了适应大屏幕的平板电脑, 当然现在它仍然是平板APP UI设计的宠儿,而且我们普通手机开发也会加入这个Fragment, 我们可以把他看成一个小型的Activity,又称Activity片段!
下面这张图就是一个fragment分别对应手机与平板的处理图
2.碎片的使用方式
2.1静态加载Fragment
第一步:
定义一个Fragment的xml文件
我定义的是left_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="@+id/button"
android:text="Button"
/>
</LinearLayout>
第二步:
自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView()方法
在该方法中调用:inflater.inflate()方法加载Fragment的布局文件,接着返回加载的view对象
- 在继承Fragment时,会有两个不同包下的Fragment供我们选择(如下图)
一个是AndroidX库中的androidx.fragment.app.Fragment ,一个是系统内置的android.app.Fragment ,这里我们选择AndroidX库中的Fragment ,因为它可以让Fragment的特性在所有Android系统版本中保持一致,而系统内置的Fragment在Android 9.0版本中已被废弃。
//这里的名字就叫LeftFragment
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.left_fragment,container,false);
return view;
}
}
第三步:
在需要加载Fragment的Activity对应的布局文件中添加fragment的标签, 记住,name属性是全限定类名哦,就是要包含Fragment的包名,
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
第四步:
Activity在onCreate( )方法中调用setContentView()加载布局文件即可!
2.2动态添加碎片
实现流程
2.3在碎片中返回栈
我们成功实现了向活动中动态添加碎片的功能,不过你尝试一下就会发现,通过点击按钮添加了一个碎片之后,这时按下Back键程序就会直接退出。如果这里我们想模仿类似于返回栈的效果,按下Back键可以回到上一个碎片,该如何实现呢?
其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,修改MainActivity中的代码,如下所示.
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
2.4Fragment管理与Frangment事务
2.5Fragment与Activity的交互
- 组件获取
Fragment获得Activity中的组件: getActivity().findViewById(R.id.list);
Activity获得Fragment中的组件(根据id和tag都可以):getFragmentManager.findFragmentByid(R.id.fragment1);
-
数据传递
①Activity 传递数据给Fragment:在Activity中创建Bundle数据包,调用Fragment实例的setArguments(bundle) 从而将Bundle数据包传给Fragment,然后Fragment中调用getArguments获得 Bundle对象,进行解析就可以了
②Fragment传递数据给Activity
1.在Fragment定义一个接口,接口中定义抽象方法,你要传什么类型的数据参数就设置为什么类型;
2.接着写一个调用接口中的抽象方法,把要传递的数据传过去
3.再接着就是Activity了,调用Fragment提供的那个方法,然后重写抽象方法的时候进行数据 的读取就可以了!!!③Fragment与Fragment之间的数据互传
找到要接受数据的fragment对象,直接调用setArguments传数据进去就可以了
通常的话是replace时,即fragment跳转的时候传数据的,那么只需要在初始化要跳转的Fragment 后调用他的setArguments方法传入数据即可!
如果是两个Fragment需要即时传数据,而非跳转的话,就需要先在Activity获得f1传过来的数据, 再传到f2了,就是以Activity为媒介
3.碎片的生命周期
3.1 碎片的状态
- 运行状态
当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。 - 暂停状态
当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。 - 停止状态
当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态,或者通过调用FragmentTransaction的 remove()、replace()方法将碎片从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。 - 销毁状态
碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进入到销毁状态。
活动中有的回调方法,碎片中几乎都有,不过碎片还提供了一些附加的回调方法,那我们就重点看一下这几个回调:
- onAttach()。当碎片和活动建立关联的时候调用。
- onCreateView()。为碎片创建视图(加载布局)时调用。
- onActivityCreated()。确保与碎片相关联的活动一定已经创建完毕的时候调用。
- onDestroyView()。当与碎片关联的视图被移除的时候调用。
3.2生命周期的流程
3.3常用操作下生命周期流程
①Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume
②当我们弄出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点 onPause
③当对话框关闭,Activity又获得了焦点: onResume
④当我们替换Fragment,并调用addToBackStack()将他添加到Back栈中 onPause -> onStop -> onDestoryView !!注意,此时的Fragment还没有被销毁哦!!!
⑤当我们按下键盘的回退键,Fragment会再次显示出来: onCreateView -> onActivityCreated -> onStart -> onResume
⑥如果我们替换后,在事务commit之前没有调用addToBackStack()方法将 Fragment添加到back栈中的话;又或者退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop -> onDestoryView -> onDestory -> onDetach
内容参考:《第一行代码》——郭霖