浅析android之fragment

本文详细介绍了Fragment的概念、生命周期及其在Android开发中的应用方式。包括静态和动态使用Fragment的方法,并讲解了如何利用Fragment实现模块化和可重用性,以及如何管理Fragment的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fragment的基本概念

fragment是Activity的一部分,它必须依赖于Activity,它也有自己的生命周期,一个Activity里可以有一个或多个fragment,并且可以删除或者添加fragment,Fragment可以被多个Activity重用。
注意:support-v4库中也开发一套Fragment API,过去support-v4库是一个jar包,24.2.0版本开始,将support-v4库模块化为多个jar包,包含:support-fragment,support-ui,support-media-compat等,这么做是为了减少APK包的大小,需要哪个模块就引入哪个模块。例如:项引入support-v4库,则compile 'com.android.support:support-v4:24.2.1',如果只想引入support-fragment库,则‘com.android.support:support-fragment:24.2.1’

support库是不断更新的,因此使用support库中support.v4.app.Fragment比较好,不要使用系统自带的android.app.Fragment.如果要使用support库的Fragment,Activity必须继承FragmentActivity(AppCompatActivity是FragmentActivity的子类)
fragment的生命周期:


onAttach(Activity)
当Fragment与Activity发生关联时调用,可以通过该方法获取activity引用,还可以通过getArguments()获取参数
onCreate()
Fragment被创建时调用
onCreateView(LayoutInflater,ViewGroup,Bundle)
创建该Fragment的视图
onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
onStart()
当Fragment可见时调用
onResume()
当Fragment可见且可交互时调用
onPause()
当Fragment不可交互但可见时调用
onStop()
当Fragment不可见时调用
onDestoryView()
与onCreateView相对应,当该Fragment的视图被转移时调用
onDetach()
当Fragment和Activity解除关联时调用
与onAttach相对应,当Fragment与Activity关联被取消时调用

上面的方法只有onCreateView()在重写时不用写super方法,其他都需要

fragment的好处:
1.模块化:不必要把所有代码全部写在Activity中,而是把代码写在各自的Fragment中
2.可重用:多个Activity可重用一个Fragment
3.克适配:根据屏幕尺寸,屏幕方向,能够方便地实现不同的布局。
fragment的核心类:
Fragment:Fragment的基类,任何创建的Fragment都需要继承该类
FragmentManager:管理和维护Fragment,是抽象类,具体的实现类是FragmentManagerIMpI.
FragmentTransaction:对Fragment的添加,删除等操作都需要通过事务方式进行,是抽象类,具体的实现类是BackStackRecord
Nested Fragment(Fragment内部嵌套Fragment的能力),通过getChildFragmentManager()能够获得管理自Fragment的FragmentManager,在子Fragment中可以通过getParentFragment()获得父Fragment.

使用fragment的方式:
1.静态使用:

用一个例子简单说明:一个布局有标题和内容,标题和内容都是是fragment。

上面是内容fragment

上面是标题fragment
下面是MainActivity的布局文件:

核心思想就是·将fragment当作是view来看待加进Activity中,所有控件的事务都交给各自的fragment去做。静态添加的缺点是一旦添加了就不能删除

2.动态使用

只讲述使用support.v4.app.Fragment,首先activity必须继承FragmnetActivity.
1.在Activity定义所要添加的fragment的实例

    private FragmentManager manager;//为了管理Activity中的fragments,需要使用FragmentManager

 那么使用FragmentManager可以做的工作有哪些呢:
1.得到Activity中存在的fragment:使用findFragmentById()或findFragmentByTag()方法。
2.将fragment弹出back stack:popBackStack:将back stack中最后一次的fragment转换弹出。如果没有可以出栈的东西,返回false.
   这个函数是异步的:它将弹出栈的请求加入队列,但是这个动作直到应用回到事件循环才会执行。
3.为back stack加上监听器
****注意****
当使用Fragment时,可以通过用户交互来执行一些动作,比如增加、移除、替换等,所有这些的改变构成一个集合,这个集合叫做一个transaction.
可以调用FragmentTransaction中的方法来处理这个transaction,并且可以将transaction存进由activity管理的back stack中,这样用户就可以进行fragment变化的回退操作。
那么如何得到这个实例呢?
manager = getSupportFragmentManager();


    public TabDynamicFragment tabDynamicFragment;
    public TabMeFragment tabMeFragment;
    public TabMessageFragment tabMessageFragment;


 private void showFragment(int page) {


        FragmentTransaction ft = manager.beginTransaction();
        // 想要显示一个fragment,先隐藏所有fragment,防止重叠
        hideFragments(ft);
        switch (page) {
            case 0://主页
                // 如果fragment1已经存在则将其显示出来
                if (drFragment != null)
                    ft.show(drFragment);
                    // 否则添加fragment1,注意添加后是会显示出来的,replace方法也是先remove后add
                else {
                    drFragment = new DRFragment();
                    ft.add(R.id.tabhome_fragment, drFragment);
                }
                flag = 1;
                changecolor(flag);
                break;
            case 1://动态
                if (tabDynamicFragment != null)
                    ft.show(tabDynamicFragment);
                else {
                    tabDynamicFragment = new TabDynamicFragment();
                    ft.add(R.id.tabhome_fragment, tabDynamicFragment);
                    if (isFirstEnterDynamic) {
                        isFirstEnterDynamic = false;
                        SharedPreferences.Editor edit = sp.edit();
                        edit.putString("onceDynamic", "onceDynamic");
                        edit.commit();
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                tabDynamicFragment.showGuideDialog();
                            }
                        }, 300);


                    }
                }
                flag = 2;
                changecolor(flag);
                break;
            case 2://消息
                if (tabMessageFragment != null) {
                    ft.show(tabMessageFragment);
                } else {
                    tabMessageFragment = new TabMessageFragment();
                    ft.add(R.id.tabhome_fragment, tabMessageFragment);
                }
                flag = 3;
                changecolor(flag);
                break;
            case 3://我的页面
                if (tabMeFragment != null) {
                    ft.show(tabMeFragment);
                    //  tabMeFragment.doCheckEvent();
                } else {
                    tabMeFragment = new TabMeFragment();
                    ft.add(R.id.tabhome_fragment, tabMeFragment);
                }
                flag = 4;
                changecolor(flag);
                break;
        }
        ft.commit();//事务提交,很关键
    }


    // 当fragment已被实例化,相当于发生过切换,就隐藏起来
    public void hideFragments(FragmentTransaction ft) {
        if (drFragment != null)
            ft.hide(drFragment);
        if (tabDynamicFragment != null)
            ft.hide(tabDynamicFragment);
        if (tabMessageFragment != null)
            ft.hide(tabMessageFragment);
        if (tabMeFragment != null)
            ft.hide(tabMeFragment);
    }

实现Fragment懒加载

实现的目标是,当Fragment对我们可见时,才进行网络加载,然后再解析数据,更新UI.
在Fragment中有一个setUserVisibleHint这个方法,而且这个方法是优于onCreate()方法的,所以可以作为Fragment的一个生命周期来看待,它会通过·1isVisibleToUser
告诉当前Fragment是否可见
可以重写setUserVisibleHint方法,然后可见进行网络加载数据
public void setUserVisibleHint(boolean isVisibleToUser){
   if(isVisibleToUser){
    pullData();
    super.setUserVisibleHint(isVisbleToUser);
}

}
根据实际用途使用懒加载
因为setUserVisibleHint(boolea isVisibleToUser)方法是比onCreate更早调用的,但是一般在加数据时,都会在数据加载完成时进行UI更新,所以有一个问题,假如
拉取数据是秒回,但是没有进行UI绑定,或者Adapter初始化,就无法更新UI,但是可以通过另一个方法getUserVisibleHint(),这个方法判断当前Fragment是否可见,可以在
一系列变量初始化在判断是否可见,若可见进行数据拉取

if(getUserVisibleHint){
  pullData();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值