被虐了,做某公司笔试时,发现自己连个Fragment的生命周期都写不详细。平时敲代码,有开发工具的便利,有网上各大神的文章,就算忘了也很容易的可以查到,但当要自己不借助外界,却发现自己似乎对该知识点并不是很理解。
所以,还是老老实实的做好笔记。本篇随笔介绍的是Fragment,这类的文章网上很多,题主还是个小渣,就只是简单的记录,借机巩固基础,如果有理解错的地方,还望指点一下。
Fragment介绍
关于Fragment的介绍网上很多,有说是用来支持不同屏幕手机的布局的,官网上也介绍说能给用户提供一种动态、灵活的交互体验。
但对于一个新手来说,学习的层面,很少需要去考虑到适配不同屏幕手机的需求。毕竟新手更多的是学习一个知识点如何使用,而不是做一个产品出来。所以新手对Fragment接触的频率可能会比较少,毕竟简单的程序Activity就可以满足了。
题主也是小渣一枚,对于Fragment的理解,更多的是觉得它的动态增加、移除、替换非常实用。
因为新手学习常常是模仿一些比较出名的App,很多App都会有统一的标题栏、底部栏之类的,更换的只是内容区的界面,这种情况如果还只是用Activity来实现,项目里就会有大量重复的代码,后期需要修改某个地方,将是一件恐怖的事。所以,这时候使用Fragment就非常好了。
Fragment生命周期
Fragment是依附于Activity存活的,网上也说可以将Fragment看成是迷你型的Activity,这样一来,Fragment的生命周期也就很容易理解了。先附上张图:
因为Fragment是依附于Activity的,所以当Activity执行完onCreate后,Fragment也就相应的执行它的回调函数。
这里也很好理解,首先是先关联,关联成功后创建对象,接着创建视图。摧毁时正好反过来,先摧毁视图,然后摧毁对象,最后再取消关联。其他回调函数都跟Activity一样。
刚学习时可以把日志打印出来,自己琢磨几遍也就清楚流程了,如下图:
①onCreate --> onResume (onResume后Activity/Fragment就处于运行状态:可见,有焦点,可交互)
②onStop --> onRestart --> onResume (当活动从后台重新进入前台时执行的回调函数)
③摧毁过程
Fragment使用
首先是了解,了解完后就要开始学习该怎么使用了。网上都介绍说有两种方式,静态和动态。其实也就是要么在布局文件xml中直接把Fragment当成普通的组件使用,要么在java代码中动态的添加、替换、移除。有些类似于广播的使用方式。
①静态使用
首先先创建一个Fragment的布局文件:fragment_phone.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"><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="PHONT" />
</LinearLayout>
然后创建一个FragmentPhone类继承自Fragment:FragmentPhone.java
public class FragmentPhone extends Fragment {@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {Log.d(TAG, "onCreateView");return inflater.inflate(R.layout.fragment_phone, container, false);}}
至于为什么要创建这个类,题主的理解是:因为要把Frament当成普通的组件在布局文件中使用,但Fragment的布局是由我们自己定义决定的,所以可以把它当成是自定义组件,那就按照自定义UI的方式来操作了。
onCreateView也就类似于Activity的onCreate,我们需要在这里为我们的Fragment指定相应的布局文件。
最后就是在Activity的布局文件中使用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"tools:context="com.iwin.fragment01.MainActivity"tools:showIn="@layout/app_bar_main"><fragmentandroid:name="com.iwin.fragment01.FragmentPhone"android:layout_width="match_parent"android:layout_height="match_parent" />
</RelativeLayout>
使用fragment标签,和android:name属性来指定具体的Fragment就大功告成了。
总结下,静态使用方法:创建Fragment布局文件 ---> 创建FragmentPhone类继承Fragment,在onCreateView方法中指定布局文件 ---> 使用fragment标签和android:name属性来指定使用哪个Fragment。
②动态使用
首先创建Fragment布局文件,跟静态使用时第一步一样。
然后创建Fragment***类继承Fragment,在onCreateView方法中指定布局文件,仍然跟静态使用的第二步一样。
最后在Activity类的onCreate方法中使用:
public class MainActivity extends AppCompatActivity {private FragmentPhone fphone;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i(TAG,"onCreate");setContentView(R.layout.activity_main);if (savedInstanceState == null){FragmentManager fm = getFragmentManager();FragmentTransaction ft = fm.beginTransaction();fphone = new FragmentPhone();ft.add(R.id.content,fphone);ft.commit();}}
}
先获取FragmentManager的对象,然后开启一个事务,指定操作(添加,替换,移除,隐藏等),最后提交事务就可以了。
至于为什么要通过事务来操作Fragment,题主的理解是:因为一个过程我们可以指定多个操作,比如隐藏当前Fragmetn,然后再添加一个新的Fragment进来等等,如果在完成部分操作时程序出问题了,那么这时界面就会处于一个奇怪的现状。而事务可以保证操作要么全部完成,要么一个都不做。
其实也就是从数据库的事务概念来理解了,也不知道对不对,至少这样理解可以加深点印象。
对Fragment的操作(添加,替换,移除等)需要通过FragmentTransaction提供的API来操作,FragmentRransaction实例可以通过FragmentManager类的benginTransaction()获得。而FragmentManager的实例则可以通过Activity的getFragmentManager()获取。
对Fragment的操作示例:(ft是FragmentTransaction 的一个实例对象。)
添加
ft.add(R.id.content,fphone);
第一个参数是指定一个来放置你的Fragment的ViewGroup(FrameLayout等),第二个参数就是一个Fragment的实例对象。
替换
ft.replace(R.id.content,fcamera);
参数同上。
总结下,动态使用Fragment前两步跟静态一样,需要创建Fragment布局文件和类 ---> 通过Activity的getFragmentManager()获取FragmentManager实例 ---> 通过FragmentManager的beginTransaction()获取FragmentTransaction的实例 ---> 调用获取FragmentTransaction的API,如ft.add(要放置Fragment的ViewGroup,Fragment实例) ---> 提交事务如ft.commit()
暂时就先记录这些基础的知识点了,后面等用多了Fragment,对于与Activity的通信,以及一些其他特殊的用法熟悉了再来做笔记。