1. 前言

       这几天接到一个坑的任务,领导要我做一个Android 蓝牙APK,要求是在平板上使用并且横屏分页显示,一边显示蓝牙广播搜索的设备,另一边存放指定已过滤的设备。

       在Android中横屏显示,并且分页,自然而然就想到了Fragment,于是抽空学习一下Fragment的用法,并且在使用过程中遇到findFragmentById 返回为null。

今天遇到这个问题,真是头疼死了,找了很多资料都说是这样子使用,在原本可以运行的项目中的findFragmentByid返回值为null,原本可以运行的项目,竟然运行报错。

因此才有这一篇文章。

 

2. 基本概念

      Fragment,又称碎片,也可以说是Activity的一个片段,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。

  • Fragment是依赖于Activity的,不能独立存在的。
  • 一个Activity里可以有多个Fragment。
  • 一个Fragment可以被多个Activity重用。
  • Fragment有自己的生命周期,并能接收输入事件。
  • 我们能在Activity运行时动态地添加或删除Fragment。

Fragment的优势有以下几点:

  • 模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
  • 可重用(Reusability):多个Activity可以重用一个Fragment。
  • 可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。

 

3. Fragment生命周期(参考菜鸟教程《Fragment基本概述》)

 

4. Fragment 使用(参考菜鸟教程《Fragment基本概述》)

Fragment 使用有两种方式,分为静态加载Fragment 动态加载Fragment

4.1 静态加载Fragment

对于静态加载需要注意的是:

4.1.1. 通过xml的方式添加,缺点是一旦添加就不能在运行时删除

4.1.2 自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView()方法 在该方法中调用:Inflater.inflate()方法加载Fragment的布局XML文件,接着返回加载的view对象,在Inflater.inflat方法中的第三个参数必须为false,因为它还要停靠在容器中。

第三个参数是false,因为在Fragment内部实现中,会把该布局添加到container中,如果设为true,那么就会重复做两次添加,则会抛如下异常:

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call 

4.1.3 在需要加载Fragment的Activity或者父Fragment(Fragment 包含Fragment) 对应的布局文件中添加fragment的标签, 记住,name属性是全限定类名哦,就是要包含Fragment的包名,如下:

                                
public abstract class BaseFragment extends Fragment{    protected View mRootView;    protected Activity mActivity;    @Override    public void onCreate(Bundle saveInstanceState)    {        super.onCreate(saveInstanceState);        mActivity = getActivity();    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)    {        return initView();    };    //当fragment 依赖的activity onCreate方法结束时使用    @Override    public void onActivityCreated(Bundle saveInstanceState)    {        super.onActivityCreated(saveInstanceState);        initData();    }    //子类必须初始化    public abstract View initView();    //子类初始化数据    public abstract void initData();}

4.2 动态加载Fragment(参考菜鸟教程《Fragment基本概述》)

4.2.1 在动态添加方式中,首先需要Activity 或者 父Fragment 中有一个

一个容器存放Fragment,一般是FrameLayout,因此在Activity的布局文件中加入FrameLayout:

在onCreate()中,通过以下代码将Fragment添加进Activity中

if (bundle == null) {    getSupportFragmentManager().beginTransaction()        .add(R.id.container, Fragment1.newInstance("hello world"), "f1")        .commit();}

使用动态方式,add()方法的第三个参数是fragment的tag名,指定tag的好处是后续我们可以通过Fragment1 frag = getSupportFragmentManager().findFragmentByTag("f1")从FragmentManager中查找Fragment对象。

 

5. Fragment与Activity的交互(参考菜鸟教程《Fragment基本概述》)

 

5.1Fragment向Activity传递数据

在Fragment中定义接口,并让Activity实现该接口。

5.2 Activity向Fragment传递数据

Activity向Fragment传递数据比较简单,获取Fragment对象,并调用Fragment的方法即可,比如要将一个字符串传递给Fragmen

5.3Fragment之间通信

由于Fragment之间是没有任何依赖关系的,因此如果要进行Fragment之间的通信,建议通过Activity作为中介,不要Fragment之间直接通信,如下:

 

6. 在Fragment 中获取控件的方法,

mRootView = UIUtils.inflate(R.layout.fragment_home_left_layout);        mRefreshLayout = (SwipeRefreshLayout) mRootView.findViewById(R.id.refreshLayout);        mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()        {            @Override            public void onRefresh() {                scanLeDevice(true);            }        });        listView = (MyListView) mRootView.findViewById(R.id.listView1);

7. Activity中获取Fragment组件的方法

首先getFragmentManager 、getSupportFragmentManager这个两个FragmentManager用的最多,Fragment是安卓3.0以后引入的API,FragmentManager是管理Fragment的片段管理器,直接使用,再

Fragment获得Activity中的组件: getActivity().findViewById(R.id.list);
Activity获得Fragment中的组件(根据id和tag都可以):getFragmentManager.findFragmentByid(R.id.fragment1);

 

8. Fragment 嵌套使用时,获取组件方法

当Fragment嵌套Fragment时(也就是说你的Fragment里面还有子Fragment),里面需要用getChildFragmentManager来获得FragmentManager,再使用findViewById(R.id.list), 或者findFragmentByid(R.id.fragment1);

 

关于Fragment 一些基本的认识就这些了,学习还要继续,付出总有回报的。

 

 

 

参考:

《Android Fragment 非常详细的一篇》

Fragment嵌套Fragment中getChildFragmentManager的问题

对于Fragment的一些理解

更多相关文章

  1. Android接口回调,最简单的理解方式
  2. Android(安卓)M 动态权限获取
  3. Android下的Service的基本用法
  4. Android版本兼容器
  5. 游走Android系列之Service
  6. Android中 Intent/Bundle传递对象取值为null的剖析以及Serializa
  7. Android第三方应用集成到Android系统的解决方法
  8. android AIDL RPC 机制
  9. android Handler的使用(二)

随机推荐

  1. android,ExpandableList,将被选中的group置
  2. 数据存储之文件存储
  3. android之RadioButton与RadioGroup,CheckB
  4. freeglut中提供的几种立体几何对象绘制的
  5. okHttp3学习总结
  6. android 中 Proguard 和JNI 相关
  7. 关于 SimpleAdapter 适配器
  8. Ubuntu下ndk-build编译C++出错:non-numeri
  9. Android(安卓)FFmpeg系列——6 Java 获取
  10. android fragment+ FragmentTabHost+view