• Android UI Fragment探索之基础


    一、概述

      fragment是一种控制器对象,activity可以委托它完成一些任务。通常这此任务是就管理用户界面。受管理的界面可以是一整屏,也可以是屏幕的一部分。

      activity视图含有可提供fragment视图插入的位置,如果有多个fragment要插入,activity也可以提供多个可插入位置。使用fragment可以绕过activity的一些限制规则。

      PS:fragment本身不具有在屏幕上显示视图的能力,因此,只有将它的视图放置于activity的视图层级结构中,fragment视图才有显示在屏幕上的能力。

     二、Fragment生命周期

      Fragment的生命周期类似于activity的生命周期,它具有暂停、停止、运行状态,也拥有可以覆盖的方法,用来在关键节点完成一些任务。需要注意的是,fragment的生命周与activity的生命周期的一个关键区别,在于,fragment的生命周期不是由OS管理,而是托管给activity来管理。OS无人知晓activity用来管理视图fragment。

                   (此图来自于Android书籍权威指南) 

    三、托管方式

    • 添加fragment到activity布局中,就等同于,将fragment及其视图与activity视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。
    • 在activity代码添加fragment,可以灵活管理fragment视图,控制其添加和移除。
       1 <?xml version="1.0" encoding="utf-8"?>
       2 <LinearLayout
       3     xmlns:android="http://schemas.android.com/apk/res/android"
       4     xmlns:tools="http://schemas.android.com/tools"
       5     android:orientation="vertical"
       6     android:layout_width="match_parent"
       7     android:layout_height="match_parent">
       8 
       9     <EditText
      10         android:id="@+id/crime_title"
      11         android:layout_width="match_parent"
      12         android:layout_height="wrap_content"
      13         android:hint="@string/crime_title_hint"/>
      14 
      15 </LinearLayout>

    四、实现fragment生命周期方法

     1 public class CrimeFragment extends Fragment
     2 {
     3     private Crime mCrime;
     4     private EditText mEditText;
     5 
     6     @Override
     7     public void onCreate(Bundle savedInstanceState)
     8     {
     9         super.onCreate(savedInstanceState);
    10         mCrime = new Crime();
    11     }
    12 
    13     @Override
    14     public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
    15     {
    16         View v = inflater.inflate(R.layout.fragment_crime, parent, false);
    17 
    18         mEditText = (EditText)v.findViewById(R.id.crime_title);
    19         mEditText.addTextChangedListener(new TextWatcher()
    20         {
    21             @Override
    22             public void beforeTextChanged(CharSequence s, int start, int count, int after)
    23             {
    24                 mCrime.setmTitle(s.toString());
    25             }
    26 
    27             @Override
    28             public void onTextChanged(CharSequence s, int start, int before, int count)
    29             {
    30 
    31             }
    32 
    33             @Override
    34             public void afterTextChanged(Editable s)
    35             {
    36 
    37             }
    38         });
    39 
    40         return v;
    41     }
    42 }

    以上代码中,需要注意以下几点:

    1. 在Fragment类中,onCreate(...)方法的访问权限是公共的(public),而在activity类中,onCreate(...)方法访问权限是被保护的(protected)。
    2. 类似于activity,fragment同样具有存储及获取状态的Bundle。
    3. 在fragment中onCreate(...)方法中,没有生成fragment视图。而是配置了fragment实例,但创建fragment视图是通过onCreateView(...)方法实现的,如下:
      1 public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){}

      通过该方法生成fragment的视图,然后,将生成的View视图返回给activity。

    五、FragmentManager

      fragmentManager类负责管理fragment,并将它们的视图添加到activity的视图层级结构中。

      具体管理的事务:

    • 管理fragment队列。
    • 管理fragment事务的回退栈。

    在activity子类中,添加fragmentManager,用于管理fragment视图。

     1 public class CrimeActivity extends FragmentActivity
     2 {
     3     @Override
     4     protected void onCreate(Bundle savedInstanceState)
     5     {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_crime);
     8 
     9         // 获取fragmentmanager对象,fragment的队列
    10         FragmentManager fm = getFragmentManager();
    11         // 通过资源ID,在fragment队列中,获取到指定的fragment对象
    12         Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
    13         if (null == fragment)
    14         {
    15             // 如未获取到fragment对象,则创建对象并添加到fragment队列中
    16             fragment = new CrimeFragment();
    17             fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
    18         }
    19     }
    20 }

    以上代码需要注意的是以下几点:

    • FragmentManager类是管理fragment视图的队列。

    容器资源ID主要作用:

    • 告知FragmentManager,fragment视图显示在activity视图中的什么位置。
    • R.id是fragment视图在FragmentManager队列中的唯一标识。

    六、回顾FragmentManager与Fragment生命周期

    在activity处于停止、暂停或运行状态下时,添加fragment会发生什么?

    • activity处于停止或暂停状态时,FragmentManager立即驱使fragment快速跟上activity的步伐,直到与activity的最新状态同步。
    • activity处于运行状态时,fragment的生命周期会依次调用:
      • onAttach(Activity)
      • onCreate(Bundle)
      • onCreateView(...)
      • onActivityCreate(...)
      • onStart()
      • onResume()

    PS:fragment状态与activity状态时时刻刻在保持一致,即使不一致,也是在去保持一致状态的路上。

  • 相关阅读:
    《Orange'S:一个操作系统的实现》与上一版之比较
    IPC
    末日帝国——Agile公司的困境 (2)
    取经学道真经验——你听过这么享受的培训吗
    数据库设计指南(五)数据库小技巧
    软件项目开发典型风险一览
    数据库设计指南(四)保证数据的完整性
    官网的Ext direct包中.NET版的问题
    软件项目开发应写的13类文档
    面试EJB常考题
  • 原文地址:https://www.cnblogs.com/naray/p/5286461.html
Copyright © 2020-2023  润新知