Fragment——创建一个Fragment
Creating a Fragment
You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities). This lesson shows how to extend the Fragment
class using the Support Library so your app remains compatible with devices running system versions as low as Android 1.6.
Note: If you decide that the minimum API level your app requires is 11 or higher, you don't need to use the Support Library and can instead use the framework's built inFragment
class and related APIs. Just be aware that this lesson is focused on using the APIs from the Support Library, which use a specific package signature and sometimes slightly different API names than the versions included in the platform.
Before you begin this lesson, you must set up your Android project to use the Support Library. If you have not used the Support Library before, set up your project to use the v4 library by following the Support Library Setupdocument. However, you can also include the app bar in your activities by instead using the v7 appcompatlibrary, which is compatible with Android 2.1 (API level 7) and also includes the Fragment
APIs.
Create a Fragment Class
To create a fragment, extend the Fragment
class, then override key lifecycle methods to insert your app logic, similar to the way you would with an Activity
class.
One difference when creating a Fragment
is that you must use the onCreateView()
callback to define the layout. In fact, this is the only callback you need in order to get a fragment running. For example, here's a simple fragment that specifies its own layout:
1 import android.os.Bundle; 2 import android.support.v4.app.Fragment; 3 import android.view.LayoutInflater; 4 import android.view.ViewGroup; 5 6 public class ArticleFragment extends Fragment { 7 @Override 8 public View onCreateView(LayoutInflater inflater, ViewGroup container, 9 Bundle savedInstanceState) { 10 // Inflate the layout for this fragment 11 return inflater.inflate(R.layout.article_view, container, false); 12 } 13 }
Just like an activity, a fragment should implement other lifecycle callbacks that allow you to manage its state as it is added or removed from the activity and as the activity transitions between its lifecycle states. For instance, when the activity's onPause()
method is called, any fragments in the activity also receive a call toonPause()
.
More information about the fragment lifecycle and callback methods is available in the Fragments developer guide.
Add a Fragment to an Activity using XML
While fragments are reusable, modular UI components, each instance of a Fragment
class must be associated with a parent FragmentActivity
. You can achieve this association by defining each fragment within your activity layout XML file.
Note: FragmentActivity
is a special activity provided in the Support Library to handle fragments on system versions older than API level 11. If the lowest system version you support is API level 11 or higher, then you can use a regular Activity
.
Here is an example layout file that adds two fragments to an activity when the device screen is considered "large" (specified by the large
qualifier in the directory name).
res/layout-large/news_articles.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <fragment android:name="com.example.android.fragments.HeadlinesFragment" android:id="@+id/headlines_fragment" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.android.fragments.ArticleFragment" android:id="@+id/article_fragment" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout>
Tip: For more about creating layouts for different screen sizes, read Supporting Different Screen Sizes.
Then apply the layout to your activity:
import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); } }
If you're using the v7 appcompat library, your activity should instead extend AppCompatActivity
, which is a subclass of FragmentActivity
. For more information, read Adding the App Bar).
Note: When you add a fragment to an activity layout by defining the fragment in the layout XML file, youcannot remove the fragment at runtime. If you plan to swap your fragments in and out during user interaction, you must add the fragment to the activity when the activity first starts, as shown in the next lesson.
你可以认为fragment是activity中模块化的一部分,它拥有自己的生命周期,接收自己的输入事件,可以在acvitity运行过程中添加或者移除(有点像"子activity",可以在不同的activity里面重复使用)。这一课教我们将学习继承Support Library 中的Fragment,使应用在Android1.6这样的低版本上仍能保持兼容。
Note: 如果APP的最低API版本是11或以上,则不必使用Support Library,我们可以直接使用API框架中的Fragment,本课主要讲解基于Support Library的API,Support Library有一个特殊的包名,有时与平台版本的API名字存在略微不同。
开始这节课之前,你须要在你的工程上使用Support Library。如果你没有使用过,可以根据文档 Support Library Setup 来设置项目使用。同时,你使用包含app bar的 v7 appcompat library。v7 appcompat library 兼容Android2.1(API level 7),也包含了Fragment APIs。
创建一个Fragment类
创建一个自定义的Fragment类,须要继承Fragment类,然后在关键的生命周期方法中插入APP的业务逻辑,就像activity一样。
区别之一是当创建Fragment的时,必须重写onCreateView()生命方法来定义布局。其实,如果是仅仅想要Fragment运行起来,这是唯一一个需要我们重写的回调方法。比如,下面是一个自定义布局的示例fragment.
1 import android.os.Bundle; 2 import android.support.v4.app.Fragment; 3 import android.view.LayoutInflater; 4 import android.view.ViewGroup; 5 6 public class ArticleFragment extends Fragment { 7 @Override 8 public View onCreateView(LayoutInflater inflater, ViewGroup container, 9 Bundle savedInstanceState) { 10 // Inflate the layout for this fragment 11 return inflater.inflate(R.layout.article_view, container, false); 12 } 13 }
当activity添加或者移除fragment以及activity生命周期发生变化时,fragment就像activity一样通过其生命周期函数管理其状态。例如,当activity的onPause()被调用时,它里面的所有fragment的onPause()方法也会被触发。
更多关于fragment的声明周期和回调方法,详见Fragments 开发者指南.
下面介绍两种添加fragment到activity的方法
用XML将fragment添加到activity
当一些fragment可以在不同Activity间可重用、成模块时,Fragment所属的每一个Activity实例都必须继承自FragmentActivity。只有这样,我们才能在Activity所属的XML布局文件中定义相应fragment来实现这种关联。
(译者注:这句话与英文直译过来差别很大,译者也是参阅其他内容意译的,因为感觉直译逻辑不通,很多内容都没有说出来,比如这段话的隐藏意思:因为兼容性问题,通过FragmentActivity 我们才可以获取到FragmentManager,之后才能关联到xml中的fragment)
Notes:FragmentActivity是Support Library提供的一个特殊activity ,用于处理API11版本以下的fragment。如果我们APP中的最低版本大于等于11,则可以使用普通的Activity。
下面是一个XML布局的例子,当屏幕被认为是large(用目录名称中的large
字符来区分)时,它在布局中显示为两个fragment.
res/layout-large/news_articles.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <fragment android:name="com.example.android.fragments.HeadlinesFragment" android:id="@+id/headlines_fragment" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.android.fragments.ArticleFragment" android:id="@+id/article_fragment" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout>
Notes:更多关于不同屏幕尺寸创建不同布局的信息,请阅读Supporting Different Screen Sizes
然后将这个布局文件用到activity中。
import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); } }
如果用的是 v7 appcompat library,activity应该改为继承AppCompatActivity,它是FragmentActivity的一个子类(更多关于这方面的内容,请阅读Adding the App Bar)。
Note:当通过XML布局文件的方式将Fragment添加进activity时,Fragment是不能被动态移除的。如果想要在用户交互的时候fragment之间能够自由切换,必须在activity启动后,再将fragment添加进activity。这部分内容将在下节课阐述。
部分翻译来自: