Android

Java安卓学习总结(十一)

有关在onStart()中调用方法

2020年5月26日:上一章节的挑战练习,我遇到的一个障碍是,从子activity返回主activity中时,剩余可以作弊次数不能及时显示。czt告诉我可以将操作写在onStart()方法里面,尝试了一下将updateQuestion()写在onStart()中之后发现确实可以,并且由于旋转屏幕带来的对updateQuestion()方法的再次调用也可以取消了。

UI fragment与fragment管理器

有关Activity与fragment

将Activity的一部分的视图界面交给fragment来实现,目的是用专门的机制去包装关键组件以实现更灵活的界面。原本实现一个较为复杂的界面可能需要多个activity来执行,现在可以选择在一个activity上使用多个fragment来实现。

好处是由于所有界面全在一个activity上实现,在视图切换时无需销毁activity。这样原本要多个activity实现的界面,通过利用fragment,只需要一个activity来托管就能实现。

fragment和activity的实现在结构上很相似。他们有着相似的生命周期与其方法,都能使用bundle来保存与获取状态信息。实际上,fragment相当于activity上的activity,这么说是因为,activity由操作系统来调用,而fragment是由activity来调用。比如Fragment.onCreate(Bundle)是公共方法,所有的activity理论上都有机会去调用它,而Activity.onCreate(Bundle)是受保护的。

有关onCreateView()

与activity不同的是,fragment的视图不在onCreate()中生成,而是在onCreateView()中。

  • onCreate是指创建该fragment,类似于Activity.onCreate,你可以在其中初始化除了view之外的东西;
  • onCreateView是创建该fragment对应的视图,你必须在这里创建自己的视图并返回给调用者。

很奇怪为什么这两个要分开来,上网查阅一番之后发现:

Fragment 的 onCreate 方法是在Acitivity 的 onAttachFragment() 方法调用后,onCreateView() 方法调用前执zhi行的。这个方法可以在 Activity 的 onCreate 方法返回前调用,dao所以其不能对调用 View 类型的对象。
onCreateView() 方法是在 onCreate() 方法调用后执行的。在这里可以初始化任何与 View 相关的界面元素。
总的来说 ,onCreate 先执行,完成一些与 UI 无关的 Fragment 的初始化。然后执行 onCreateView() ,初始化与界面相关的内容

意思就是Fragment可以在某个activity的onCreate()方法调用前就被调用,因此此时由于该activity还没有被初始化,所以不能托管Fragment。打个不恰当的比方,Fragment是处于静态环境下的,先于任何activity实例产生,但是其初始化又必须基于一个已经初始化的activity,所以分化为onCreate()和onCreateView()两个方法。

onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

三个参数的含义及作用
LayoutInflater inflater:作用类似于findViewById(),findViewById()用来寻找xml布局下的具体的控件(Button、TextView等),LayoutInflater inflater()用来找res/layout/下的xml布局文件
ViewGroup container:表示容器,View放在里
Bundle savedInstanceState:保存当前的状态,在活动的生命周期中,只要离开了可见阶段,活动很可能就会被进程终止,这种机制能保存当时的状态

在fragment中,必须手动调用view.findViweById()方法,而在activity中,可以直接使用findViweById(),后台会自动调用view.findViweById()方法。

有关Fragment Manager

Fragment Manager就是activity托管fragment的具体实现。Fragment Manager类负责管理fragment并将它们的视图添加到activity的视图层级结构中。

定义一个fragment,并且在fragmentManager中获取它,如果不在队列中还需要新启动一个fragment事务并将其添加到队列中。

以下代码就是启动新的fragment事务的:

if (fragment==null)
{
    fragment=new CrimeFragment();
    fm.beginTransaction().add(R.id.fragment_container,fragment).commit();
}

其中beginTransaction()开始对这个队列进行操作;add()是添加这个新的fragment事务,第一个参数是容器视图资源ID,第二个是新创建的fragment实例,add()是创建一个fragment,将fragment实例送至所选的资源视图中去。

一开始很迷为什么一个fragment事务,要用容器视图资源ID来标识一个fragment。可能是因为对于一个fragment事务而言,一个容器视图是不变的,且可以调用任意的fragment,所谓“流水的fragment,铁打的容器视图”。这也是体现了在activity代码中添加fragment的灵活性。

另外,我在获取FragmentManager时,遇到一个问题,即必须要加上支持库的前缀,即

android.support.v4.app.FragmentManager fm=getSupportFragmentManager();
        android.support.v4.app.Fragment fragment=fm.findFragmentById(R.id.fragment_container);

否则会报错:

Incompatible types.
Required: android.app.FragmentManager
Found:
android.support.v4.app.FragmentManager

有关onactivitycreate()

这一章提到了,但是没有讲用法,先挖个坑。参考

发表评论