Android中Fragment学习笔记

一、生命周期


二、静态的使用Fragment

直接在布局文件中使用fragment标签,可以将fragment跟其他布局控件一样去使用。

1、Fragment1和Fragment2布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is fragment #1"
        android:textColor="#000000"
        android:textSize="25sp"/>

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is fragment #2"
        android:textColor="#000000"
        android:textSize="25sp"/>

</LinearLayout>

2、MainActivity布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context="com.example.fragmenttest.MainActivity">

    <fragment
        android:name="com.example.fragmenttest.Fragment1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <fragment
        android:name="com.example.ragmenttest.Fragment2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

</LinearLayout>

3、Fragment1和Fragment2源文件

public class Fragment1  extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment1, container, false);
    }
}

public class Fragment2  extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment2, container, false);
    }
}

4、MainActivity源文件

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

三、动态使用Fragment

就是动态的添加Fragment,也就是不需要在布局文件中使用fragment标签。
跟上面静态添加不同的是Activity的布局文件和MainActivity源文件,其他相同。

Activity的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/fragment"
    tools:context="com.example.fragmenttest.MainActivity">
</LinearLayout>

MainActivity文件

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        WindowManager wm = getWindowManager();
        Display d = wm.getDefaultDisplay();
        if (d.getWidth() > d.getHeight()) {
            Fragment fragment1 = new Fragment1();
            fragmentTransaction.replace(R.id.fragment, fragment1);
        } else {
            Fragment fragment2 = new Fragment2();
            fragmentTransaction.replace(R.id.fragment, fragment2);
        }
        fragmentTransaction.commit();
    }
}

四、Fragment家族常用的API

Fragment常用的三个类:
android.app.Fragment 主要用于定义Fragment
android.app.FragmentManager 主要用于在Activity中操作Fragment
android.app.FragmentTransaction 保证一些列Fragment操作的原子性

Fragment

主要掌握声明周期方法

public void onAttach(Activity activity)
public void onCreate(Bundle savedInstanceState)
public View onCreateView(LayoutInflater inflater, ViewGroup container,  
                Bundle savedInstanceState)
public void onActivityCreated(Bundle savedInstanceState)
public void onStart()
public void onResume()
public void onPause()
public void onStop()
public void onDestroyView()
public void onDestroy()
public void onDetach()

FragmentManager

为了管理Activity中的fragments,需要使用FragmentManager,调用Activity中的getFragmentManager()方法可以得到FragmentManager,因为FragmentManager的API是在Android 3.0,也即API level 11开始引入的,所以对于之前的版本,需要使用support library中的FragmentActivity,并且使用getSupportFragmentManager()方法。

用FragmentManager可以做的工作有:

  • 得到Activity中存在的fragment:使用findFragmentById()或findFragmentByTag()方法。
  • 将fragment弹出back stack:popBackStack(),将back stack中最后一次的fragment转换弹出。如果没有可以出栈的东西,返回false。这个函数是异步的,它将弹出栈的请求加入队列,但是这个动作直到应用回到事件循环才会执行。
  • 为back stack加上监听器:addOnBackStackChangedListener()
FragmentTransaction
得到FragmentTransaction类的实例:
FragmentManager fragmentManager = getFragmentManager();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

每个transaction是一组同时执行的变化的集合。
  • transaction.add() 
往Activity中添加一个Fragment
  • transaction.remove() 
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
  • transaction.replace()
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
  • transaction.hide()
隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
  • transaction.show()
显示之前隐藏的Fragment
  • transaction.detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
  • transaction.attach()
重建view视图,附加到UI上并显示。
  • transaction.addToBackStack(null);
将当前的fragment存放到回退栈中,点击back键会回到上一个fragment。
  • transatcion.commit();
提交一个事务

当你移除一个fragment的时候,如果commit()之前没有调用addToBackStack(),那个fragment将会是destroyed;如果调用了addToBackStack(),这个fragment会是stopped,可以通过返回键来恢复。


五、Fragment与Activity通信
a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法
b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。
c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。

handler方案:
public class MainActivity extends FragmentActivity{ 
  //声明一个Handler 
  public Handler mHandler = new Handler(){       
      @Override
       public void handleMessage(Message msg) { 
            super.handleMessage(msg);
             ...相应的处理代码
       }
 }
 ...相应的处理代码
} 

public class MainFragment extends Fragment{ 
      //保存Activity传递的handler
       private Handler mHandler;
       @Override
       public void onAttach(Activity activity) { 
            super.onAttach(activity);
           //这个地方已经产生了耦合,若还有其他的activity,这个地方就得修改 
            if(activity instance MainActivity){ 
                  mHandler =  ((MainActivity)activity).mHandler; 
            }
       }
       ...相应的处理代码
 }

该方案存在的缺点:
  •  fragment对具体的Activity存在耦合,不利于Fragment复用
  • 不利于维护,若想删除相应的Activity,Fragment也得改动
  • 没法获取Activity的返回数据
广播方案:
具体的代码就不写了,说下该方案的缺点:
  • 用广播解决此问题有点大材小用了,广播的意图是用在一对多,接收广播者是未知的情况
  • 广播性能肯定会差
  • 传播数据有限制
EventBus方案
可以参考: Eventbus的基本使用
缺点:
  • EventBus是用反射机制实现的,性能上会有问题
  • EventBus难于维护代码
  • 没法获取Activity的返回数据
接口方案
//MainActivity实现MainFragment开放的接口 
  public class MainActivity extends FragmentActivity implements FragmentListener{ 
        @override
         public void toH5Page(){ }
       ...其他处理代码省略
   } 

    public class MainFragment extends Fragment{

         public FragmentListener mListener;  
        //MainFragment开放的接口 
        public static interface FragmentListener{ 
            //跳到h5页面
           void toH5Page();
         }

         @Override 
        public void onAttach(Activity activity) { 
              super.onAttach(activity); 
              //对传递进来的Activity进行接口转换
               if(activity instance FragmentListener){
                   mListener = ((FragmentListener)activity); 
              }
         }
         ...其他处理代码省略 
  }
  这种方案应该是既能达到复用,又能达到很好的可维护性。问题就是如果项目大了,接口多了就不易于管理了。

参考文章:

欢迎关注我的公众号:DroidMind

精品内容,独家发布

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值