Android Fragment
来源:互联网 发布:淘宝直通车点击率低 编辑:程序博客网 时间:2024/05/17 22:47
官方
http://developer.android.com/intl/zh-cn/guide/components/fragments.html
博客
http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html
android fragment
创建一个fragment,首先需要继承Fragment类,然后在关键的生命周期方法中插入APP的逻辑,就像activity一样。
其中一个区别是当创建Fragment的时,必须重写onCreateView()回调方法来定义布局。事实上,这是使Fragment运行起来,唯一一个需要我们重写的回调方法。比如,下面是一个自定义布局的示例fragment.
import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.ViewGroup;public class ArticleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.article_view, container, false); }}
就像activity一样,当fragment从activity添加或者移除、当activity生命周期发生变化时,fragment通过生命周期回调函数管理其状态。例如,当activity的onPause()被调用时,它里面的所有fragment的onPause()方法也会被触发。
更多关于fragment的声明周期和回调方法,详见Fragments developer guide.
用XML将fragment添加到activity
fragments是可重用的,模块化的UI组件,每个Fragment的实例都必须与一个FragmentActivity关联。我们可以在activity的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>
android:name="com.akm.fragment.ArticleFragment" 需要完整的包名+类名, 否则会提示如下错误:
07-21 11:35:20.339: E/AndroidRuntime(19777): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment .HeadlinesFragment: make sure class name exists, is public, and has an empty constructor that is public
07-21 11:35:20.339: E/AndroidRuntime(19777): at android.support.v4.app.Fragment.instantiate(Fragment.java:401)
07-21 11:35:20.339: E/AndroidRuntime(19777): at android.support.v4.app.Fragment.instantiate(Fragment.java:369)
07-21 11:35:20.339: E/AndroidRuntime(19777): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:272)
07-21 11:35:20.339: E/AndroidRuntime(19777): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
07-21 11:35:20.339: E/AndroidRuntime(19777): ... 21 more
然后将这个布局文件用到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应该改为继承ActionBarActivity,ActionBarActivity是FragmentActivity的一个子类(更多关于这方面的内容,请阅读Adding the Action Bar)。
Note:当通过XML布局文件的方式将Fragment添加进activity时,Fragment是不能被动态移除的。如果想要在用户交互的时候把fragment切入与切出,必须在activity启动后,再将fragment添加进activity。
构建灵活的界面
在设计支持各种屏幕尺寸的应用时,你可以在不同的布局配置中重复使用 Fragment ,以便根据相应的屏幕空间提供更出色的用户体验。
例如,一次只显示一个 Fragment 可能就很适合手机这种单窗格界面,但在平板电脑上,你可能需要设置并列的 Fragment,因为平板电脑的屏幕尺寸较宽阔,可向用户显示更多信息。
图 1: 两个 Fragment,显示在不同尺寸屏幕上同一 Activity 的不同配置中。在较宽阔的屏幕上,两个 Fragment 可并列显示;在手机上,一次只能显示一个 Fragment,因此必须在用户导航时更换 Fragment。
利用 FragmentManager
类提供的方法,你可以在运行时添加、移除和替换 Activity 中的 Fragment,以便为用户提供一种动态体验。
在运行时向 Activity 添加 Fragment
你可以在 Activity 运行时向其添加 Fragment,而不用像上一课中介绍的那样,使用 <fragment>
元素在布局文件中为 Activity 定义 Fragment。如果你打算在 Activity 运行周期内更改 Fragment,就必须这样做。
要执行添加或移除 Fragment 等事务,你必须使用 FragmentManager
创建一个 FragmentTransaction
,后者可提供用于执行添加、移除、替换以及其他 Fragment 事务的 API。
如果 Activity 中的 Fragment 可以移除和替换,你应在调用 Activity 的 onCreate()
方法期间为 Activity 添加初始 Fragment(s)。
在处理 Fragment(特别是在运行时添加的 Fragment )时,请谨记以下重要规则:必须在布局中为 Fragment 提供 View
容器,以便保存 Fragment 的布局。
下面是上一课所示布局的替代布局,这种布局一次只会显示一个 Fragment。要用一个 Fragment 替换另一个 Fragment, Activity 的布局中需要包含一个作为 Fragment 容器的空 FrameLayout
。
请注意,该文件名与上一课中布局文件的名称相同,但布局目录没有 large
这一限定符。因此,此布局会在设备屏幕小于“large”的情况下使用,原因是尺寸较小的屏幕不适合同时显示两个 Fragment。
res/layout/news_articles.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
在 Activity 内部,使用 Support Library API 调用 getSupportFragmentManager()
以获取 FragmentManager
,然后调用 beginTransaction()
创建 FragmentTransaction
,同时调用 add()
添加 Fragment。
你可以使用同一个 FragmentTransaction
对 Activity 执行多 Fragment 事务。当你准备好进行更改时,必须调用commit()
。
例如,下面介绍了如何为上述布局添加 Fragment :
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); // 确认 Activity 使用的布局版本包含 // fragment_container FrameLayout if (findViewById(R.id.fragment_container) != null) { // 不过,如果我们要从先前的状态还原, // 则无需执行任何操作而应返回 // 否则就会得到重叠的 Fragment 。 if (savedInstanceState != null) { return; } // 创建一个要放入 Activity 布局中的新 Fragment HeadlinesFragment firstFragment = new HeadlinesFragment(); // 如果此 Activity 是通过 Intent 发出的特殊指令来启动的, // 请将该 Intent 的 extras 以参数形式传递给该 Fragment firstFragment.setArguments(getIntent().getExtras()); // 将该 Fragment 添加到“fragment_container”FrameLayout 中 getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, firstFragment).commit(); } } }
由于该 Fragment 已在运行时添加到 FrameLayout
容器中,而不是在 Activity 布局中通过 <fragment>
元素进行定义,因此该 Activity 可以移除和替换这个 Fragment 。
用一个 Fragment 替换另一个 Fragment
替换 Fragment 的步骤与添加 Fragment 的步骤相似,但需要调用 replace()
方法,而非 add()
。
请注意,当你执行替换或移除 Fragment 等 Fragment 事务时,最好能让用户向后导航和“撤消”所做更改。要通过 Fragment 事务允许用户向后导航,你必须调用 addToBackStack()
,然后再执行 FragmentTransaction
。
注意:当你移除或替换 Fragment 并向返回堆栈添加事务时,已移除的 Fragment 会停止(而不是销毁)。如果用户向后导航,还原该 Fragment,它会重新启动。如果你没有向返回堆栈添加事务,那么该 Fragment 在移除或替换时就会被销毁。
替换 Fragment 的示例:
// 创建 Fragment 并为其添加一个参数,用来指定应显示的文章 ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // 将 fragment_container View
中的内容替换为此 Fragment , // 然后将该事务添加到返回堆栈,以便用户可以向后导航 transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // 执行事务 transaction.commit();
addToBackStack()
方法可接受可选的字符串参数,来为事务指定独一无二的名称。除非你打算使用FragmentManager.BackStackEntry
API 执行高级 Fragment 操作,否则无需使用此名称
示例源码下载
官方DEMO下载 FragmentBasics.zip
- Android Fragment---创建Fragment
- Android Fragment---管理Fragment
- Android Fragment---创建Fragment
- Android Fragment---管理Fragment
- (Android) Fragment
- Android Fragment
- Android fragment
- Android Fragment
- Android Fragment
- android Fragment
- android fragment
- fragment android
- android Fragment
- Android Fragment
- android fragment
- Android Fragment
- Android Fragment
- android Fragment
- 今天的生活是由3年前决定的
- Spring配置定时器的xml文件
- 人们为什么对性知识的了解是那么的少?
- 最优化方法(3)带约束问题的最优性条件及求解方法
- Maven的安装、配置及使用入门(原文转载)
- Android Fragment
- Android----打包常见错误
- mysql使用root登陆及密码修改
- [hdu4436]str2int
- 职场中你该如何控压?
- NOJ1063冒泡排序
- CharSequence 与String的区别
- 人们为什么对于美好的事物总是那么憧憬?
- 如何利用XMLSpy工具测试Webservice?