前言

fragment是从android3.0开始提出来的,用来支持大屏幕设备的ui设计。通过将activity划分为多个fragment,不仅提高了设计的灵活性,而且可以在程序运行时改变它们的特征,比如动态的修改,替换已有的fragment等等。

fragment的角色是相当于activity中ui的一个子集或者说是activity中的一个模块,可以通过组合多个fragment来构造一个多个面板的界面。由于fragment嵌入在activity中,因此它的生命周期受到activity的影响,一旦activity停掉,它里面所有的fragment也都会被摧毁。

可以在activity的布局文件中通过声明<fragment>标签来填充它的布局,同时也可以通过代码将它加到已经存在的ViewGroup中,因为fragment布局实际上就是ViewGroup的子树。

新建一个Fragment

首先需要了解的是fragment的生命周期,如下图所示:

可以看出调用的先后顺序是:

  • onCreate  这里可以用来初始化一些当fragment停掉时候你仍想保存的组件
  • onCreateView  这里可以用来绘制fragment的用户界面,因此必须返回一个view
  • onPause  当fragment被移走或者替换时调用,可以在这里commit changes

一般可以继承fragment类来创建自己的fragment,同时亦有几个有用的fragment基类供我们继承:

  1. DialogFragment  也就是浮动在Activity上面的fragment,这种对话框可以供用户返回,便于管理,是google推荐的做法。
  2. ListFragment  就是包含ListView的Fragment,用来显示列表等。
  3. PreferenceFragment  可以用来显示用户选项的设置。

一般来说,要创建Fragment,第一步就是创建一个Fragment的子类,并在onCrateView方法中填充布局:

public static class ExampleFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragment//resourceID,ViewGroup, whether the inflated layout should be//attached to the ViewGroup during inflationreturn inflater.inflate(R.layout.example_fragment, container, false);}
}

第二步就是将fragment添加到activity中,可以在activity的布局文件中声明,如:

<?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>

这样一来,当创建activity的布局时,就会初始化每一个fragment,并且调用它们的onCreateView方法,获取fragment的布局,然后插入到ViewGroup下面。

除了使用布局文件之外,还可以用程序进行添加:

FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

前两行用来获取碎片事务FragmentTransaction,后三行用来添加一个fragment,add方法的第一个参数是要放置的ViewGroup,第二个参数是要添加的fragment。

Fragment的管理

通过fragmentManager可以做一下事情:

  • 获取fragment,通过findFragmentById或者findFragmentByTag
  • 将Fragment从栈中移除,通过popBackStack方法
  • 为back stack注册监听器

相信这里的细节还有很多,暂时先不介绍。

Fragment的事务

fragment的一大亮点就是可以动态增加,删除,替换fragment,而这是通过fragmentTransaction来实现的。一旦获取了事务的实例,就可以通过调用add,remove,replace方法完成上述功能,接下来通过commit方法提交事务就可以了。

// 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();

除此之外还可以调用addToBackStack方法将fragment添加到back stack中,用户按下返回键时,就会跳到back stack顶部的fragment。调不调用它的区别在于,如果没有它,fragment被remove后就彻底销毁了,再也不能恢复,如果调用了它,fragment就不会销毁而是stop,这样就可以恢复,因为fragment的状态都被保存在了back stack上面。

commit方法的作用是调度到activity的主线程中执行,并且事务的提交必须要在onSaveInstanceState之前。

和Activity的通信

fragment也是可以和它所在的activity通信的,比如可以通过getActivity()方法得到所在的activity,相应的,activity也可以调用FragmentManager的findFragmentById方法获取某一个fragment的引用。

有时候需要在fragment和activity之间共享事件,如activity有一个fragment,是用来显示文章的列表的,当用户点击了某一项,activity需要检测到这个事件,同时更改另一个fragment从而显示出相应的文章内容。这时可以这么做,在fragment中定义事件监听的接口,然后让activity实现这个接口。然后,这个fragment就可以调用接口中的某些方法来通知activity了。fragment中可以在onAttach里面将activity强制转化为接口的实现类,从而确保能成功调用接口中的方法。

public static class FragmentA extends ListFragment {OnArticleSelectedListener mListener;...// Container Activity must implement this interfacepublic interface OnArticleSelectedListener {public void onArticleSelected(Uri articleUri);}...@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);try {mListener = (OnArticleSelectedListener) activity;} catch (ClassCastException e) {throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");}}...@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {// Append the clicked item's row ID with the content provider UriUri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);// Send the event and Uri to the host activitymListener.onArticleSelected(noteUri);}...
}

例子

该例子来源于api demo,用到了很典型的两个fragment,一个是TitlesFragment,用来显示一个列表,另一个是DetailsFragment,用来显示选中item的详细信息。此外,该程序还考虑到了屏幕的横竖屏问题,如果是竖屏的话,没有足够的地方显示第二个Fragment,就单独启动一个Activity。源码如下:

/*** Demonstration of using fragments to implement different activity layouts.* This sample provides a different layout (and activity flow) when run in* landscape.*/
public class FragmentLayout extendsActivity {@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.fragment_layout);}/*** This is a secondary activity, to show what the user has selected* when the screen is not large enough to show it all in one activity.*/public static class DetailsActivity extendsActivity {@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {//If the screen is now in landscape mode, we can show the//dialog in-line with the list so we don't need this activity.
finish();return;}if (savedInstanceState == null) {//During initial setup, plug in the details fragment.DetailsFragment details = newDetailsFragment();details.setArguments(getIntent().getExtras());getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();}}}/*** This is the "top-level" fragment, showing a list of items that the* user can pick.  Upon picking an item, it takes care of displaying the* data to the user as appropriate based on the currrent UI layout.*/public static class TitlesFragment extendsListFragment {booleanmDualPane;int mCurCheckPosition = 0;@Overridepublic voidonActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);//Populate list with our static array of titles.setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));//Check to see if we have a frame in which to embed the details//fragment directly in the containing UI.View detailsFrame =getActivity().findViewById(R.id.details);mDualPane= detailsFrame != null && detailsFrame.getVisibility() ==View.VISIBLE;if (savedInstanceState != null) {//Restore last state for checked position.mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);}if(mDualPane) {//In dual-pane mode, the list view highlights the selected item.
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);//Make sure our UI is in the correct state.
showDetails(mCurCheckPosition);}}@Overridepublic voidonSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putInt("curChoice", mCurCheckPosition);}@Overridepublic void onListItemClick(ListView l, View v, int position, longid) {showDetails(position);}/*** Helper function to show the details of a selected item, either by* displaying a fragment in-place in the current UI, or starting a* whole new activity in which it is displayed.*/void showDetails(intindex) {mCurCheckPosition=index;if(mDualPane) {//We can display everything in-place with fragments, so update//the list to highlight the selected item and show the data.getListView().setItemChecked(index, true);//Check what fragment is currently shown, replace if needed.DetailsFragment details =(DetailsFragment)getFragmentManager().findFragmentById(R.id.details);if (details == null || details.getShownIndex() !=index) {//Make new fragment to show this selection.details =DetailsFragment.newInstance(index);//Execute a transaction, replacing any existing fragment//with this one inside the frame.FragmentTransaction ft =getFragmentManager().beginTransaction();if (index == 0) {ft.replace(R.id.details, details);}else{ft.replace(R.id.a_item, details);}ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);ft.commit();}}else{//Otherwise we need to launch a new activity to display//the dialog fragment with selected text.Intent intent = newIntent();intent.setClass(getActivity(), DetailsActivity.class);intent.putExtra("index", index);startActivity(intent);}}}/*** This is the secondary fragment, displaying the details of a particular* item.*/public static class DetailsFragment extendsFragment {/*** Create a new instance of DetailsFragment, initialized to* show the text at 'index'.*/public static DetailsFragment newInstance(intindex) {DetailsFragment f= newDetailsFragment();//Supply index input as an argument.Bundle args = newBundle();args.putInt("index", index);f.setArguments(args);returnf;}public intgetShownIndex() {return getArguments().getInt("index", 0);}@OverridepublicView onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {if (container == null) {//We have different layouts, and in one of them this//fragment's containing frame doesn't exist.  The fragment//may still be created from its saved state, but there is//no reason to try to create its view hierarchy because it//won't be displayed.  Note this is not needed -- we could//just run the code below, where we would create and return//the view hierarchy; it would just never be used.return null;}ScrollView scroller= newScrollView(getActivity());TextView text= newTextView(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[getShownIndex()]);returnscroller;}}}

View Code

转载于:https://www.cnblogs.com/cubika/p/3177782.html

Android的Fragment介绍相关推荐

  1. Android 进阶 Fragment 介绍和使用 (一)

    Fragment概述 Fragment是activity的界面中的一部分或一种行为.你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一 ...

  2. Android之Fragment的详细介绍和使用方法

    一.Fragment的基础知识介绍 1.1概述 1.1.1 特性 Fragment是activity的界面中的一部分或一种行为.可以把多个Fragment组合到一个activity中来创建一个多界面 ...

  3. android碎片按钮,Android 碎片(Fragment)

    Android 碎片(Fragment) 碎片是活动的一部分,使得活动更加的模块化设计.我们可以认为碎片是一种子活动. 下面是关于碎片的重要知识点 - 碎片拥有自己的布局,自己的行为及自己的生命周期回 ...

  4. Android之Fragment使用简介

    Fragment是Android 3.0 (API level 11)后推出的新功能.Android3.0以前的版本也能用Fragment,不过得给工程导入一个android-support-v4.j ...

  5. Kotlin on Android 开发环境介绍

    Kotlin 被 Google 采纳为 Android 开发一级编程语言,到现在也一年多了,我们团队从去年 10 月份开始部分项目尝试用 Kotlin 开发,到现在决定推广到全部项目,因为一旦用上 K ...

  6. 三个activity之间跳转 数据传递_第二百四十二回:Android中Fragment之间的数据传递概述...

    各位看官们大家好,上一回中咱们说的是Android中Activity之间数据传递的例子,这一回咱们说的例子是Fragment之间的数据传递.闲话休提,言归正转.让我们一起Talk Android吧! ...

  7. 【Android】Fragment的简单笔记

    被虐了,做某公司笔试时,发现自己连个Fragment的生命周期都写不详细.平时敲代码,有开发工具的便利,有网上各大神的文章,就算忘了也很容易的可以查到,但当要自己不借助外界,却发现自己似乎对该知识点并 ...

  8. Android之Fragment 真正的完全解析(上)

    转载出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragme ...

  9. Android之Fragment(二)

    本文主要内容 如何管理Fragment回退栈 Fragment如何与Activity交互 Fragment与Activity交互的最佳实践 没有视图的Fragment的用处 使用Fragment创建对 ...

最新文章

  1. Ubuntu 系统安装Visual Studio Code
  2. 混淆视听的感脚(二)
  3. miniconda3 安装numpy_OpenCV4在Ubuntu1810/1604安装
  4. linux动态库查找路径以及依赖关系梳理
  5. 的硬件报错_工程师经验:78%的硬件失效罪魁祸首 —— 焊接问题
  6. 可信云认证累计达20项,腾讯云技术创新能力再获专业认可
  7. Requests Header | Http Header
  8. 资深架构师自述:程序员的黄金奋斗时期是前5年
  9. WEBPACK+ES6+REACT入门(5/7)-在React中为按钮绑定点击事件
  10. Win10:fastboot驱动问题解决方案
  11. 3D图形渲染及数字图像处理算法相关文集
  12. python3下操作SVN
  13. 微信小助手:专为mac微信3.1.0发行!支持发朋友圈!支持僵尸粉清理
  14. 如何做好互联网广告销售
  15. 格子地图 像素坐标 地图坐标 转化
  16. 99乘法口诀表用python写_python 99乘法口诀表
  17. 服务器主板显示ba,为什么我的设计器不能显示,但是可以调通,主板信息读出发生错误...
  18. php开发his软件,HIS系统(his管理系统)V3.0.1 官网版
  19. 华为鸿蒙OS 2.0系统流畅度实测:差距到底多大?
  20. 多维数组(2019.10.25)

热门文章

  1. 替换字符串列表中字符串
  2. 后Kubernetes时代的微服务
  3. 策略模式、观察者模式、代理模式、装饰模式 应用场景和实现
  4. springMvc 传子 bean 中有bean
  5. gdb 收到SIGPIPE信号
  6. 基于图像分割的立体匹配方法
  7. Myeclipse5.5获取注册码
  8. Excel2007数据透视表学习(四)改变数据透视表布局
  9. 数据库中使用自增量字段与Guid字段作主键的性能对比(补充篇)-----转
  10. 固定宽度弹性布局(以适应各种各辨率)