《安卓开发官方文档》学习笔记四Fragment
文章开始把我喜欢的这句话送个大家:这个世界上还有什么比自己写的代码运行在一亿人的电脑上更酷的事情吗,如果有那就是让这个数字再扩大十倍
创建 Fragment 时,必须重写 onCreateView() 回调方法来定义布局。事实上,这是唯一一个为使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) {
// 拉伸该 Fragment 的布局
return inflater.inflate(R.layout.article_view, container, false);
}
}
1.可以在Activity 运行时向其添加Fragment
2.可以在Activity 布局中通过 <fragment>
元素进行定义
在处理Fragment(特别是在运行时添加的Fragment)时,请谨记以下重要规则:必须在布局中为Fragment 提供 View 容器,以便保存Fragment 的布局。
在Activity 中,用Support Library API 调用 getSupportFragmentManager() 以获取 FragmentManager,然后调用 beginTransaction() 创建 FragmentTransaction,然后调用 add() 添加Fragment。你可以使用同一个 FragmentTransaction 对Activity 执行多Fragment 事务。当你准备好进行更改时,必须调用 commit()。
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 并为其添加一个参数,用来指定应显示的文章
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();
与其他Fragment 交互
所有Fragment 之间的交互应通过与之关联的Activity 来完成。两个Fragment 之间不应直接交互。
为了允许fragment和它的Activity通信,你应该fragment类中定义一个接口并在Activity中实现它。Fragment在onAttach()回调函数中获取接口的具体实现的对象。后面,fragment就可以调用接口中的方法实现与Activity的通信。
为了接收回调事件,宿主Activity 必须实现在Fragment 中定义的接口。
例如,下面的Activity 实现了上面例子中的接口。实现onArticleSelected()
方法。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// 用户从 HeadlinesFragment 选择了一篇文章的标题
// 在这里做点什么,以显示该文章
}
}
//Fragment中的结构为:
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// 容器 Activity 必须实现该接口
// (译注:“容器 Activity”意即“包含该 Fragment 的 Activity”)
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// 确认容器 Activity 已实现该回调接口。否则,抛出异常
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
现在fragment可以通过使用实现了OnHeadlineSelectedListener
接口的
mCallback
实例
调用onArticleSelected()
方法(或其他在接口中的方法)将消息传递给
Activity
。
例如,当用户点击列表条目时,Fragment中的下面的方法将被调用.Fragment用于回调接口将事件传递给父活动。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// 向宿主 Activity 传送事件
mCallback.onArticleSelected(position);
}
- getSharedPreferences() -如果需要多个通过名称参数来区分的共享偏好文件,名称可以通过第一个参数来指定。可在app中通过任何一个上下文执行该方法。
- getPreferences() -当活动仅需要一个共享偏好文件时。因为该方法会检索活动下默认的共享偏好文件,并不需要提供文件名称。