Android Fragment详解
来源:互联网 发布:旅游软件排行 编辑:程序博客网 时间:2024/05/16 00:44
一. Fragment介绍
Fragment是Android honeycomb 3.0新增的概念,Fragment名为碎片不过却和Activity十分相似,下面介绍下Android Fragment的作用和用法。Fragment用来描述一些行为或一部分用户界面在一个Activity中,你可以合并多个fragment在一个单独的activity中建立多个UI面板,同时重用fragment在多个activity中.你可以认为fragment作为一个activity中的一节模块 ,fragment有自己的生命周期,接收自己的输入事件,你可以添加或移除从运行中的activity.
一个fragment必须总是嵌入在一个activity中,同时fragment的生命周期受activity而影响,举个例子吧,当activity 暂停,那么所有在这个activity的fragments将被destroy释放。然而当一个activity在运行比如resume时,你可以单独的操控每个fragment,比如添加或删除。
Fragment作为Android 3.0的新特性,有些功能还是比较强大的,比如 合并两个Activity,如图
如上图所示,用Activity A 表示文章标题列表,ActivityB表示文章具体内容。我们可以看到两个Activity通过两个Fragment合并到一个Activity的布局方式,对于平板等大屏幕设备来说有着不错的展示面板。不过因为Fragment和Activity的生命周期都比较复杂,下图表示的fragments的生命周期:
Activity、Fragment分别对比下:
两个的生命周期很类似,也息息相关。
创建一个fragment你必须创建一个Fragment的子类或存在的子类,比如类似下面的代码
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.android_fragment, container, false);
}
}
onCreate()
当fragment创建时被调用,你应该初始化一些实用的组件,比如在fragment暂停或停止时需要恢复的
onCreateView()
当系统调用fragment在首次绘制用户界面时,如果画一个UI在你的fragment你必须返回一个View当然了你可以返回null代表这个fragment没有UI.
那么如何添加一个Fragment到Activity中呢? Activity的布局可以这样写
<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.android.cwj.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.android.cwj.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
最后提醒大家Fragment存在于Activity的ViewGroup中,按照继承关系大家就可以了解他的结构。
二、 Android Fragment使用
通常地 fragment做为宿主activity UI的一部分, 被作为activity整个view hierarchy的一部分被嵌入.
一、在activity的layout文件中声明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:id 属性提供一个唯一ID.
- 为 android:tag 属性提供一个唯一字符串.
- 如果以上2个你都没有提供, 系统使用容器view的ID.
二、使用FragmentManager将fragment添加到一个已存在的ViewGroup.
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
三、 FragmentManage FragmentTransaction介绍
FragmentManage:
FragmentManager能够实现管理activity中fragment.
1、使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment2、将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).3、使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.
FragmentTransaction:
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Create new fragment and transaction Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit();
- 必须最后调用 commit().
- 如果添加多个fragment到同一个容器, 那么添加的顺序决定了它们在view hierarchy中显示的顺序.
四、Android Fragment 实例
Fragment是Android honeycomb 3.0新增的概念,在Android——Fragment介绍、Android Fragment使用、Android FragmentManage FragmentTransaction介绍中做了关于Fragment的详细介绍。这一片主要通过一个实例了解Fragment的使用。
先看下实例效果图:
效果图的左边是一个列表,右边是列表item的详情。
先看一下布局文件(layout):
- <?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
- class="com.fragment.main.TitlesFragment"
- android:id="@+id/titles" android:layout_weight="1"
- android:layout_width="0px" android:layout_height="match_parent" />
- <FrameLayout android:id="@+id/details" android:layout_weight="1"
- android:layout_width="0px" android:layout_height="match_parent"
- android:background="?android:attr/detailsElementBackground" />
- </LinearLayout>
<?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"><fragmentclass="com.fragment.main.TitlesFragment"android:id="@+id/titles" android:layout_weight="1"android:layout_width="0px" android:layout_height="match_parent" /><FrameLayout android:id="@+id/details" android:layout_weight="1"android:layout_width="0px" android:layout_height="match_parent"android:background="?android:attr/detailsElementBackground" /></LinearLayout>
布局文件中使用了fragment标签和FrameLayout标签。Android Fragment使用 中介绍了2中嵌入Fragment的方法,这个实例中都用到,从布局文件看到有了fragment标签,这是一种使用方法,FrameLayout标签将会成为第二种加载fragment的载体view。
看一下程序实现(com.fragment.main.TitlesFragment):
- public class TitlesFragment extends ListFragment {
- int mCurCheckPosition = 0;
- int mShownCheckPosition = -1;
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- setListAdapter(new ArrayAdapter<String>(getActivity(),
- android.R.layout.simple_list_item_activated_1,
- Shakespeare.TITLES)); //使用静态数组填充列表
- if (savedInstanceState != null) {
- mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
- mShownCheckPosition = savedInstanceState.getInt("shownChoice", -1);
- }
- getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- showDetails(mCurCheckPosition);
- }
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt("curChoice", mCurCheckPosition);
- outState.putInt("shownChoice", mShownCheckPosition);
- }
- @Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- showDetails(position);
- }
- /**
- *显示listview item 详情
- */
- void showDetails(int index) {
- mCurCheckPosition = index;
- getListView().setItemChecked(index, true);
- if (mShownCheckPosition != mCurCheckPosition) {
- DetailsFragment df = DetailsFragment.newInstance(index);
- FragmentTransaction ft = getFragmentManager()
- .beginTransaction();
- ft.replace(R.id.details, df);
- ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
- ft.commit();
- mShownCheckPosition = index;
- }
- }
- }
public class TitlesFragment extends ListFragment {int mCurCheckPosition = 0;int mShownCheckPosition = -1;@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState); setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_activated_1,Shakespeare.TITLES)); //使用静态数组填充列表if (savedInstanceState != null) { mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);mShownCheckPosition = savedInstanceState.getInt("shownChoice", -1);} getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); showDetails(mCurCheckPosition);}@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putInt("curChoice", mCurCheckPosition);outState.putInt("shownChoice", mShownCheckPosition);}@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {showDetails(position);}/** *显示listview item 详情 */void showDetails(int index) {mCurCheckPosition = index;getListView().setItemChecked(index, true);if (mShownCheckPosition != mCurCheckPosition) {DetailsFragment df = DetailsFragment.newInstance(index); FragmentTransaction ft = getFragmentManager().beginTransaction();ft.replace(R.id.details, df);ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);ft.commit();mShownCheckPosition = index;}}}
TitlesFragmentTitlesFragment继承自Fragment的子类ListFragment,使用了一个静态数组填充列表,重写了onListItemClick方法,showDetails方法展示ListView item的详情。
DetailsFragment df = DetailsFragment.newInstance(index);//获取详情Fragment的实例
FragmentTransaction ft = getFragmentManager().beginTransaction();//获取FragmentTransaction 实例
ft.replace(R.id.details, df); //使用DetailsFragment 的实例
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();//提交
这里就使用到了Android Fragment使用中介绍的第二种加载fragment的方法。看一下DetailsFragment :
- public class DetailsFragment extends Fragment {
- /** * Create a new instance of DetailsFragment, initialized to * show the text at 'index'. */
- public static DetailsFragment newInstance(int index) {
- DetailsFragment f = new DetailsFragment();
- // Supply index input as an argument.
- Bundle args = new Bundle();
- args.putInt("index", index);
- f.setArguments(args);
- return f;
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- if (container == null) {
- return null;
- }
- ScrollView scroller = new ScrollView(getActivity());
- TextView text = new TextView(getActivity());
- int padding = (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources()
- .getDisplayMetrics());
- text.setPadding(padding, padding, padding, padding);
- scroller.addView(text);
- text.setText(Shakespeare.DIALOGUE[getArguments().getInt("index", 0)]);
- return scroller;
- }
- }
public class DetailsFragment extends Fragment {/** * Create a new instance of DetailsFragment, initialized to * show the text at 'index'. */public static DetailsFragment newInstance(int index) {DetailsFragment f = new DetailsFragment();// Supply index input as an argument. Bundle args = new Bundle();args.putInt("index", index);f.setArguments(args);return f;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {if (container == null) { return null;}ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources().getDisplayMetrics());text.setPadding(padding, padding, padding, padding);scroller.addView(text);text.setText(Shakespeare.DIALOGUE[getArguments().getInt("index", 0)]);return scroller;}}
DetailsFragment 中使用newInstance(int index)方法产生DetailsFragment 实例并接受整型参数,重载了onCreateView方法创建view。
- Android Fragment使用详解
- Android Fragment使用详解
- android fragment详解
- Android Fragment使用详解
- Android Fragment使用详解
- android的Fragment详解
- Android Fragment详解
- Android Fragment详解
- Android Fragment详解
- Android Fragment 详解
- Android Fragment 详解
- Android - Fragment(碎片) 详解
- Android - ToDoList(fragment) 详解
- Android Fragment 使用详解
- android fragment详解
- Android Fragment 生命周期详解
- Android详解fragment
- Android Fragment详解
- Tomcat源码学习——第1章
- iOS ibeacon后台运行相关文章
- Linux基础必懂:eth0,eth1,eth2,lo是什么意思?
- linux下qt使用svn的问题
- [leetcode][hash] Anagrams
- Android Fragment详解
- Android手机的休眠状态
- 怎样在Swift中使用CocoaPods
- shell文件读取及字符串分隔符
- 统计图形-茎叶图
- js常用函数-1
- Understanding the Objective-C Runtime
- ARM中断笔记
- 中国天气网接口类(中国天气预报)