腾讯大牛,一篇文章教你什么是 Android-Fragment-,Android 高级架构师筑基必备!
Fragment 的生命周期
因为 Fragment 必须嵌入在 Acitivity 中使用,所以 Fragment 的生命周期和它所在的 Activity 是密切相关的。
如果 Activity 是暂停状态,其中所有的 Fragment 都是暂停状态;如果 Activity 是 stopped 状态,这个 Activity 中所有的 Fragment 都不能被启动;如果 Activity 被销毁,那么它其中的所有 Fragment 都会被销毁。
但是,当 Activity 在活动状态,可以独立控制 Fragment 的状态,比如加上或者移除 Fragment。
当这样进行 fragment transaction(转换)的时候,可以把 fragment 放入 Activity 的 back stack 中,这样用户就可以进行返回操作。
Fragment 的使用相关
使用 Fragment 时,需要继承 Fragment 或者 Fragment 的子类(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以 Fragment 的代码看起来和 Activity 的类似。
使用 Support Library
Support Library 是一个提供了 API 库函数的 JAR 文件,这样就可以在旧版本的 Android 上使用一些新版本的 APIs。
比如 android-support-v4.jar.它的完整路径是:
<sdk>/extras/android/support/v4/android-support-v4.jar.
它就提供了 Fragment 的 APIs,使得在 Android 1.6 (API level 4)以上的系统都可以使用 Fragment。
为了确定没有在旧版本系统上使用新版本的 APIs,需要如下导入语句:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
同时应该将上述的包拷入 libs 项目下的 libs 文件夹,然后在项目的 Properties 中添加:右键单击项目,选 Properties,左边选 Java Build Path,然后 Add External JARs…,添加 android-support-v4.jar.
当创建包含 Fragment 的 Activity 时,如果用的是 Support Library,那么继承的就应该是 FragmentActivity 而不是 Activity。
必须实现的三个回调函数
onCreate()
系统在创建 Fragment 的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。
onCreateView()
当第一次绘制 Fragment 的 UI 时系统调用这个方法,必须返回一个 View,如果 Fragment 不提供 UI 也可以返回 null。
注意,如果继承自 ListFragment,onCreateView()默认的实现会返回一个 ListView,所以不用自己实现。
onPause()
当用户离开 Fragment 时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。
实现 Fragment 的 UI
提供 Fragment 的 UI,必须实现 onCreateView()方法。
假设 Fragment 的布局设置写在 example_fragment.xml 资源文件中,那么 onCreateView()方法可以如下写:
public static class ExampleFragment extends Fragment{@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.example_fragment, container, false);}}
onCreateView()中 container 参数代表该 Fragment 在 Activity 中的父控件;savedInstanceState 提供了上一个实例的数据。
inflate()方法的三个参数:
第一个是 resource ID,指明了当前的 Fragment 对应的资源文件;
第二个参数是父容器控件;
第三个布尔值参数表明是否连接该布局和其父容器控件,在这里的情况设置为 false,因为系统已经插入了这个布局到父控件,设置为 true 将会产生多余的一个 View G
roup。
把 Fragment 加入 Activity
当 Fragment 被加入 Activity 中时,它会处在对应的 View Group 中。
Fragment 有两种加载方式:一种是在 Activity 的 layout 中使用标签<fragment>声明;另一种方法是在代码中把它加入到一个指定的 ViewGroup 中。
另外,Fragment 它可以并不是 Activity 布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。
加载方式 1:通过 Activity 的布局文件将 Fragment 加入 Activity
在 Activity 的布局文件中,将 Fragment 作为一个子标签加入即可。
如:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragment android:name="com.example.news.ArticleListFragment"android:id="@+id/list"android:layout_weight="1"android:layout_width="0dp"android:layout_height="match_parent" /><fragment android:name="com.example.news.ArticleReaderFragment"android:id="@+id/viewer"android:layout_weight="2"android:layout_width="0dp"android:layout_height="match_parent" /></LinearLayout>
其中 android:name 属性填上你自己创建的 fragment 的完整类名。
当系统创建这个 Activity 的布局文件时,系统会实例化每一个 fragment,并且调用它们的 onCreateView()方法,来获得相应 fragment 的布局,并将返回值插入 fragment 标签所在的地方。
有三种方法为 Fragment 提供 ID:
android:id 属性:唯一的 id
android:tag 属性:唯一的字符串
如果上面两个都没提供,系统使用容器 view 的 ID。
加载方式 2:通过编程的方式将 Fragment 加入到一个 ViewGroup 中
当 Activity 处于 Running 状态下的时候,可以在 Activity 的布局中动态地加入 Fragment,只需要指定加入这个 Fragment 的父 View Group 即可。
首先,需要一个 FragmentTransaction 实例:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
(注,如果 import android.support.v4.app.FragmentManager;那么使用的是:FragmentManager fragmentManager = getSupportFragmentManager();)
之后,用 add()方法加上 Fragment 的对象:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
其中第一个参数是这个 fragment 的容器,即父控件组。
最后需要调用 commit()方法使得 FragmentTransaction 实例的改变生效。
实例
练习的例子:
写一个类继承自 Fragment 类,并且写好其布局文件(本例中是两个 TextView),在 Fragment 类的 onCreateView()方法中加入该布局。
之后用两种方法在 Activity 中加入这个 fragment:
第一种是在 Activity 的布局文件中加入<fragment>标签;
第二种是在 Activity 的代码中使用 FragmentTransaction 的 add()方法加入 fragment。
贴出代码:
自己定义的 fragment 类:
package com.example.learningfragment;
import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;
public class ExampleFragment extends Fragment{
//三个一般必须重载的方法 @Overridepublic void onCreate(Bundle savedInstanceState){// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);System.out.println("ExampleFragment--onCreate");}
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){System.out.println("ExampleFragment--onCreateView");return inflater.inflate(R.layout.example_fragment_layout, container, false);
}
@Overridepublic void onPause(){// TODO Auto-generated method stubsuper.onPause();System.out.println("ExampleFragment--onPause");}
@Overridepublic void onResume(){// TODO Auto-generated method stubsuper.onResume();System.out.println("ExampleFragment--onResume");}
@Overridepublic void onStop(){// TODO Auto-generated method stubsuper.onStop();System.out.println("ExampleFragment--onStop");}
}
fragment 的布局文件:
<?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="wrap_content"android:text="@string/num1"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"
评论