PS:文章主要是博主自学源码时记下来的新的笔记,很多东西都是自己的理解,不一定对,更不是教学文章。欢迎一起探讨,不欢迎冷嘲热讽,Thanks♪(・ω・)ノ~
源码及API地址:https://developer.android.google.cn/reference/android/app/Fragment?hl=zh-cn
头部主要记住Fragment继承自Object类,在Android3.0(API11)版本开始使用,在Android9.0(API28)被废弃……(刚学就被废了,真的sui~)
Fragment这个类是被放置在Activity中,用来充当用户界面或者行为的一个小碎片。各个Fragment之间是通过FragmentManager来相互联系的,而FragmentManager是通过Activity或者Fragment类中的getFragmentManager()方法获取得到的。
Fragment这个类可以通过很多途径达到各种各样的效果。它的核心在一个运行较大的Activity的特殊操作或者界面中得以体现(意思就是当一个Activity越大Fragment在其中越能体现出它的价值)。Fragment类是紧密依附于Activity的,不能单独运行。尽管Fragment有自己的生命周期,但是也要受到Activity的影响:比如当Activity停止运行时(就是onStop()呗),Activity中的所有Fragment也就都无法启动,又比如当Activity被销毁时(就是onDestory()呗),那么这个Activity所包含的所有Fragment也要统统被销毁。
所有的Fragment的子类必须要包含一个无参的构造函数,因为在运行环境中当一个类需要被重新实例化时,尤其是恢复阶段,就需要寻找这个无参的构造函数才能进行实例化,如果没有找到,就会在一些恢复阶段报RuntimeException异常;
从四个方面进行介绍:
就是说Fragment在Android3.0,HONEYCOMB这个版本被提出来的,对更早的版本可以用FragmentActivity进行兼容;
尽管Fragment的生命周期依附在所属的Activity中,但也有自己独有的生命周期。包括像Activity的一些基本的生命周期比如“onResume()”,Fragment与Activity的交互、对UI的生成同意很重要。(这段没太看懂,反正是为了说明Fragment有着自己的生命周期,并且这些周期与Activity交互以及UI有关联)
下面阐述Fragment生命周期:
文档把生命周期分成了两块,一块是绑定创建Fragment,一块是销毁解绑Fragment;
onAttach():Fragment与Activity关联时调用;
onCreate():初始化Fragment调用;
onCreateView():Fragment绑定UI视图调用;
onActivityCreated():Fragment在依赖的Activity的onCreate()返回后调用;
onStart():显示Fragment界面视图;
onResume():正常运行时,与用户交互;
onPause():Fragment长时间不交互,或者依赖的Activity被Pause了,或者被一个Fragment通过修改时;
onStop():Fragment长时间不可见,或者依赖的Activity被Stop了,或者被一个Fragment通过修改时;
onDestoryView():当绑定了Fragment的UI视图被移除时调用;
onDestory():最终的清理;
onDetach():与Activity解绑时调用;
PS:onDestroyView()中释放资源,例如ButterKnife在onCreateView()时通过Unbinder对象unbinder=ButterKnife.bind(this,view)绑定,在onDestoryView()中进行unbinder.unbind()解绑。
Fragment可以通过
MainActivity类及其布局:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MainFragment类及其布局:
public class MainFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main,container,false);
return view;
}
}
静态调用Fragment效果:
下面源码紧接着介绍了ListFragment的使用,但是它只贴出了部分代码,想要跑起来这个demo要简单改动一下。
源码总共有四块。
1、新建两个Fragment(TitlesFragment、DetailsFragment)把上面两大块代码贴进去。
2、新建个DetailsActivity类直接把第三块源码贴进去。
3、最后一块是MainActivity的横屏布局。而竖屏布局只用写一个fragment,如下:
4、这时候还要建一个Shakespeare类作为数据源,如下所示:
public class Shakespeare {
public static ArrayList TITLES = new ArrayList();
public static ArrayList DIALOGUE = new ArrayList();
static {
for (int i = 0; i < 50; i++) {
TITLES.add("这是第"+(i+1)+"的Item");
DIALOGUE.add("这是第"+(i+1)+"的Details");
}
}
}
然后有些小问题的地方稍微改改就能跑起来了。大致的效果就是竖屏时,只显示一个TitlesFragment列表,点击会跳转到DetailsActivity显示具体的信息,横屏时DetailsActivity会自己finish掉,回到MainActivity并调用横屏布局,左边TitlesFragment,右边是DetailsFragment。
这里有一点小优化就是把TitlesFragment代码里的
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
提出到括号前面,否则当你第一次竖屏点击一个item后横过来,高亮显示的是对应的item,但是当你继续竖屏点击其他item后再横屏,高亮显示的还是第一次点击的item。奈何个人水平有限,研究了半天不知道具体原因,个人怀疑是和adapter中调用的simple_list_item_activated_1中textview的background有关。感兴趣的可以研究研究,这里点到为止。