Fragment,简称碎片,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。以前support-v4库是一个jar包,24.2.0版本开始,将support-v4库模块化为多个jar包,包含:support-fragment, support-ui, support-media-compat等,这么做是为了减少APK包大小,你需要用哪个模块就引入哪个模块。如果想引入整个support-v4库,则compile ‘com.android.support:support-v4:24.2.1’,如果只想引入support-fragment库,则com.android.support:support-fragment:24.2.1。 下面将从一下几方面介绍Fragment:
一,Fragment的几个核心类
二,Fragment基本使用
三,Fragment生命周期
四,Fragment与activity之间的通信方式
五,Fragment的优势
六,总结
一,Fragment的几个核心类
Fragment:Fragment的基类,任何自定义创建的Fragment都需要继承该类。如:
public class Fragment1 extends Fragment{
}
FragmentManager:管理和维护Fragment。他是抽象类,具体的实现类是- FragmentManagerImpl。
FragmentTransaction:对Fragment的添加、删除等操作都需要通过事务方式进行。他是抽象类,具体的实现类是BackStackRecord。
FragmentTransaction有一些基本方法,下面给出调用这些方法时,Fragment生命周期的变化:
add(): onAttach()->…->onResume()。
remove(): onPause()->…->onDetach()。
replace(): 相当于旧Fragment调用remove(),新Fragment调用add()。
show(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为true。
hide(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为false。
detach(): onPause()->onStop()->onDestroyView()。UI从布局中移除,但是仍然被FragmentManager管理。
attach(): onCreateView()->onStart()->onResume()。
Nested Fragment(Fragment内部嵌套Fragment的能力)是Android 4.2提出的,support-fragment库可以兼容到1.6。通过getChildFragmentManager()能够获得管理子Fragment的FragmentManager,在子Fragment中可以通过getParentFragment()获得父Fragment。
二 Fragment基本使用
基本使用代码如下:
public class TabFragment extends Fragment {
private WebView webView;
private String url;
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);
Bundle bundle = this.getArguments();
url = bundle.getString("url","https://zhuanlan.zhihu.com/p/25213586");
init(view);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroyOptionsMenu() {
super.onDestroyOptionsMenu();
}
@Override
public void onDetach() {
super.onDetach();
}
public static TabFragment newInstance() {
Bundle args = new Bundle();
TabFragment fragment = new TabFragment();
fragment.setArguments(args);
return fragment;
}
private void init(View view) {
webView = view.findViewById(R.id.webview);
webView.loadUrl(url);
}
@Override
public void onDestroy() {
webView.destroy();
super.onDestroy();
}
}
Fragment 添加到activity有静态和动态两种方式
静态通过xml中的方式添加,缺点是一旦添加就不能在运行时删除。一般都不用静态添加。运行时添加,这种方式比较灵活,因此建议使用这种方式。因为Fragment并不是一个View,而是和Activity同一层次的。Activity需要有一个容器存放Fragment,一般是FrameLayout,因此在Activity的布局文件中加FrameLayout:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragments">
</FrameLayout>
然后在onCreate()中,通过以下代码将Fragment添加进Activity中。
在FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
TabFragment mAll;
if(mAll == null){
mAll = new TabFragment();
//添加Fragment到 container
transaction.add(R.id.stock_mot_more_content_fl, mAll);
}
transaction.commit();
三,Fragment生命周期
在上面的Fragment自定代码中已写出各个生命周期方法,各方法的介绍如下:
onAttach():Fragment和Activity相关联时调用。可以通过该方法获取 Activity引用,还可以通过getArguments()获取参数。
onCreate():Fragment被创建时调用。
onCreateView():创建Fragment的布局。
onActivityCreated():当Activity完成onCreate()时调用。
onStart():当Fragment可见时调用。
onResume():当Fragment可见且可交互时调用。
onPause():当Fragment不可交互但可见时调用。
onStop():当Fragment不可见时调用。
onDestroyView():当Fragment的UI从视图结构中移除时调用。
onDestroy():销毁Fragment时调用。
onDetach():当Fragment和Activity解除关联时调用。
四,Fragment与 Activity之间的通信方式
4.1 Fragment向Activity通信方式
第一种 在Activity中调用getFragmentManager()得到fragmentManager,,调用findFragmentByTag(tag)或者通过findFragmentById(id)
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
第二种 通过回调的方式,定义一个接口(可以在Fragment类中定义),接口中有一个空的方法,在fragment中需要的时候调用接口的方法,值可以作为参数放在这个方法中,然后让Activity实现这个接口,必然会重写这个方法,这样值就传到了Activity中
第三种 通过FABridge 注解方式通信
4.2 Activity向Fragment通信
1,要传的值,放到bundle对象里;
2,在Activity中创建该Fragment的对象fragment,通过调用
fragment.setArguments()传递到fragment中;
3,在该Fragment中通过调用getArguments()得到bundle对象,就能得到里面的值。
4.3 Fragement与Fragment之间通信
第一种:
通过findFragmentByTag得到另一个的Fragment的对象,这样就可以调用另一个的方法了。
第二种:
通过接口回调的方式。
第三种:
通过setArguments,getArguments的方式。
五,Fragment的优势
模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
可重用(Reusability):多个Activity可以重用一个Fragment。
可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。
六 总结
Fragment是依赖于Activity的,不能独立存在的。
一个Activity里可以有多个Fragment。
一个Fragment可以被多个Activity重用。
Fragment有自己的生命周期,并能接收输入事件。
我们能在Activity运行时动态地添加或删除Fragment。