fragment基础篇

来源:互联网 发布:淘宝图 编辑:程序博客网 时间:2024/06/08 16:39

一、fragment简介

了解fragment基本了解这三个关键词:

求同

fragment必须依托于activity,所以生命周期直接受到宿主activity的影响,一个宿主可以管理加载多个fragment。就相当于寄生一样的概念,宿主生则寄生者生,宿主死则寄生者亡。

存异

fragment可以作为activitylayout中的一部分,fragment也能定义自己的布局,当然fragment是否需要展现给用户,都是可以自己定义的。

目的

目前接触到的项目中,fragment比起activity的使用频率更高,很多时候都采用单activity宿主,多fragment的结构。这样做的好处:1. 这样比多个activity更省内存.2. 一个activiy多个fragment能有效解耦.activity承载的逻辑可以更少更清晰,其他对应的逻辑业务可以放到相对的fragment中.3. fragment有和activity一样具备ui的处理能力,也具有和宿主activity绑定的生命周期.

二、fragment生命周期

生命周期是一个很重要的东西,了解一个类的生命周期,能很轻松的决定什么时间段该干什么活,不该干什么活,有些活能不能在这里干。只有对fragment的生命周期有所掌握,才能运用自如。

生命周期介绍

下面是来源于android官网的生命周期图:
这里写图片描述

  • onAttach(Context context)
    onAttach调用是在activity的oncreate方法中,这里的context是activity,看源码传递的都是activity。

  • onCreate(Bundle savedInstanceState)
    这里的savedInstanceState和activity的oncreate的bundle类似,即fragment在回收之前保存的一些状态值。

  • onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
    inflater,container,savedInstancestate都是fragmentManager中传入的,inflater能够将一个布局文件xml加载为一个view,container是fragment要插入的父布局,一般来着activity的布局。savedInstancestate是上一个被回收activefragment保存的数据,可能为空。oncreateview的作用就是加载fragment的布局到activity中,当然如果你这个fragment没有任何的view,也可以返回null。

  • onActivityCreated(Bundle savedInstanceState)
    前面这4个方法都在activity的onCreate()中

  • onStart()
    当activity调用onstart的时候会通过fragmentManager中的dispatchStart分发,调用其中fragment的onstart,所以和activity一样,当fragment onstart可见不可操作。

  • onResume()
    同上dispatchResume分发调用fragment的onresume方法,fragment可见可操作。

  • onPause()
    同上dispatchPause分发调用fragment的onpause方法,fragment从RESUMED恢复到STARTED的状态,fragment可见不可操作。

  • onStop()
    同上dispatchStop分发调用fragment的onstop方法,fragment的最后状态变为ACTIVITY_CREATED,不可见且不可操作,同时如果activity在内存缺少的时候被回收,那么fragment也不能幸免。

  • onDestroyView()
    在onstop之后ondestroy之前被调用,状态回归CREATED,当状态变为CREATED之后,但还没有被宿主移除。

  • onDestroy()

  • onDetach()
    分发状态,ondestroy走完就接着执行onDetach。

下一篇帖子会对生命周期做详细源码分析

activity生命周期的关系

贴一张官网的图,可以先了解。至于为什么,下一篇通过源码详细分析O_O
这里写图片描述

三、fragment使用

在使用之前需要了解fragment是怎么区分身份标识的。通过Tag和Id。fragment类中有一个mTag的成员变量和一个mFragmentId成员变量,mFragmentId是非必须指定的,默认是加载的布局layout的id,当然也可以在layout中通过android:id指定其id,而mTag是添加是给定的一个String类型的tag,可以用来区分不同的fragment。即:
- Tag mTag
- Id mFragmentId
FragmentManager提供了findFragmentById和findFragmentByTag来查找对应的唯一fragment,所以这个点需要在使用之前有所了解。使用fragment的方式一般有两种:

一、直接在布局中添加fragment

android:name属性布局需要实例化的类,android:id属性提供唯一Id,即:mFragmentId,android:tag属性唯一字符串mTag。

1、 MainActivity中的布局添加fragment的布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <fragment        android:name="com.example.ervinli.demo.BaseFragment"        android:id="@+id/fragment_base"        android:layout_width="match_parent"        android:layout_height="match_parent"/></RelativeLayout>

2、fragment的需要实现onCreateView的方法加载布局

public class BaseFragment extends android.app.Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment_base, container, false);    }    }

3、R.layout.fragment_base布局文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             xmlns:tools="http://schemas.android.com/tools"             android:layout_width="match_parent"             android:layout_height="match_parent">    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@string/hello_blank_fragment"/></FrameLayout>

二、通过FragmentManager和FragmentTransaction动态添加替换

如果加载布局的id!=0,那么mFragmentId就是布局的id,如果调用用FragmentTransaction的重载方法add(int containerViewId, Fragment fragment, String tag) 那么这个参数tag,不为空那么就是mTag。
1、MainActivity中的布局添加布局

<?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">    <FrameLayout        android:id="@+id/fragment_container"        android:layout_width="match_parent"        android:layout_height="match_parent"/></LinearLayout>

2、MainActivity中添加逻辑

public class MainActivity extends Activity {    private FragmentTransaction mFragmentTransaction;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mFragmentTransaction = getFragmentManager().beginTransaction();        BaseFragment baseFragment = new BaseFragment();        mFragmentTransaction.add(R.id.fragment_container, baseFragment);        mFragmentTransaction.commit();    }}

3、R.layout.fragment_base布局文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             xmlns:tools="http://schemas.android.com/tools"             android:layout_width="match_parent"             android:layout_height="match_parent">    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@string/hello_blank_fragment"/></FrameLayout>

同样这种方法也能添加使用fragment,相比较而言,第二种比第一种更灵活,更实用。第二种方法中用到了FragmentManager、FragmentTransaction,还有为什么第二种比第一种好些,以及其他细节将会转移到下一篇博客。

0 0
原创粉丝点击