Android编程权威指南 - 第7章 UI fragment与fragment管理器

引入fragment的原因

  • 假设开发一个这样的App,新增加一系列的项目,每个项目里有对应的明细内容。
  • 如果仅仅使用Activity,想要看某一个项目的明细内容,只能新建一个Activity以显示明细。当然,这里面会涉及到项目列表的Activity的销毁,对应数据的保存,以及信息的传递。这样也可以实现,但是不具备灵活性,用户体验也不好
  • frament就是在一个Activity中实现,多个界面布局的,这样使得UI更具备灵活性。

fragment的兼容性

  • fragment是在API 11级时被引入的,也就是Android 3.0之后才被引入
  • 如果需要在API 11级前引用fragment,则需要引用android.support.app.v4.*的类库
  • 由于目前机器基本上是4.4以后的设备,所以实际开发过程中其实无需再考虑此兼容性,直接使用android.app.*类库的相关组件即可。

最简单的fragment创建例子

例子说明

  • 创建一个界面,里面包含一个文本输入框
  • 使用一个Activity,包含一个fragment

创建fragment的layout文件

此文件和之前Activity的没有区别,在一个LinearLayout中包含一个EidtText。

    
      

创建一个fragement类

  • 此类继承android.app.fragment类
  • 与Activity类似,需要覆盖onCreate函数。但是此函数只是生成了实例,并未生成fragment视图。而Activity要使用到fragment,需要引用的是视图。
  • 实现视图需要复写的onCreateView函数,函数的返回值是一个View视图对象。此函数有三个参数:android.view.LayoutInflater、android.view.ViewGroup、Bundle。前两个参数是生成布局的,Bundle参数是为了保持状态的。
  • 视图的生成是通过,LayoutInflater的inflater函数实现的,有三个参数:第一个参数是第一步创建的布局文件;第二个参数是ViewGroup,表示视图的父视图;第三个参数如果为false,表示在activity中将以代码的方式添加视图。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {    
      View v = inflater.inflate(R.layout.fragment_crime, parent, false);
      return v;
}

fragment中关联组件

  • activity中关联组件是直接使用findViewById(R.id.xxxx)
mTrueButton = (Button)findViewById(R.id.true_button);
  • fragment中不是直接使用findViewById函数,而是使用上一步创建的View对象,调用此View对象的findViewById函数来关联上对应的组件的。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {    
      View v = inflater.inflate(R.layout.fragment_crime, parent, false);    
      mTitleField = (EditText)v.findViewById(R.id.crime_title);    
      mTitleField.addTextChangedListener(new TextWatcher() {        
            public void onTextChanged(CharSequence c, int start, int before, int count) {            
                  mCrime.setTitle(c.toString());        
            }        
            public void beforeTextChanged(CharSequence c, int start, int count, int after) {        
            }        
            public void afterTextChanged(Editable c) {       
             }    
      });    
      return v;
}

将UI fragment添加到Activity中

Activity托管UI fragment的两种方式

  • 添加fragment到activity布局中去。这种方式虽然简单,但是缺乏灵活性,基本不会使用此种方式。
  • 在activity代码中添加fragment。这种方式是常用的方式

通过android.app.FragmentManager管理fragment

  • 改造activity的layout布局文件。原来布局文件里是具体的组件,而现在只用包含一个FrameLayout用于容纳fragment。
    注意需要设定id值,以保证代码可以引用到。

  • 通过getFragmentManager获取FragmentManager的实例;通过findFragmentById关联上布局文件的FrameLayout
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
  • 通过FragmentTransaction类进行fragment的添加、移除、附加、分离或替换等动作。FragmentTransaction对象,可以通过FragmentManager.beginTransaction()函数获得。
  • activity的整体代码如下:
public class CrimeActivity extends Activity {    
      @Override    
      protected void onCreate(Bundle savedInstanceState) {        
            super.onCreate(savedInstanceState);        
            setContentView(R.layout.activity_crime);        
            FragmentManager fm = getFragmentManager();        
            Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);        
            if (fragment == null) {            
                  fragment = new CrimeFragment();            
                  fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();        
            }    
      }
}

FragmentManager与fragment的生命周期

各种场景下的调用说明

  • 向FragmentManager添加fragment:onAttach(Activity)、onCreate(Bundle)、 onCreateView方法会被调用
  • 启动Activity:activity的onCreate(Bundle)、onActivityCreate()方法会被调用,随后调用" 向FragmentManager添加fragment"。当fragment被添加后,onActivityCreate方法停止
  • 向处于运行状态的activity中添加fragment: 以下fragment生命周期方法会被依次 调用: onAttach( Activity)、 onCreate( Bundle)、 onCreateView(...)、 onActivityCreate(Bundle)、onStart(),以及 onResume() 方法。

FragmentManager管理生命周期的特点

  • Activity的状态android系统是知道其处于什么样的状态的,而fragment则不会被android系统知道。只能由FragmentManager进行管理。
  • FragmentManager会保证fragment会和activity的状态保持一致
  • 当Activity被销毁时,FragmentManager会将fragment的队列保存下来。当Activity重建时,会先获取保存的fragment队列,然后重建fragment队列,从而恢复到原来的状态。
    典型的表现是,当我们在上面例子中的EditText中输入文字后,旋转手机界面,会发现在横屏状态下仍旧保存了竖屏时输入的文字信息。

你可能感兴趣的:(Android编程权威指南 - 第7章 UI fragment与fragment管理器)