当前位置:网站首页>Analyze the Add() method in Fragment management from the source code
Analyze the Add() method in Fragment management from the source code
2022-08-09 23:55:00 【Android technology stack】
前言
This article we will talk aboutFragment管理中的 Add() 方法
Add():
In our dynamic add、管理Fragment中,AddIt is the most basic method; 用法也很简单,如下就是向Activity添加一个Fragment:
getSupportFragmentManager().beginTransaction().add(R.id.fragmenta,new FragmentA()).commit();
Usually we use itFragment的时候,are more than one,Such as WeChat interface,The bottom navigation has four buttons,corresponding to four different onesFragment,If you switch the interface every time you click the bottom button like this,我们就可以使用Add()外加hide和show进行组合
下面我们简单实现一下,Here we get twoFragment,
这里我们的MainActivity的布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.shaoen.lenovo.myapplication.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/fragmenta"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/fragmenta_button"
android:text="FragmentA"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/fragmentb_button"
android:text="FragmentB"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
下面看MainActivity的内容:
package com.shaoen.lenovo.myapplication;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.shaoen.lenovo.myapplication.fragment.FragmentA;
import com.shaoen.lenovo.myapplication.fragment.FragmentB;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private String TAG=MainActivity.class.getSimpleName();
private Button fragmentA_Button;
private Button fragmentB_Button;
private FragmentTransaction transaction;
private FragmentManager fragmentManager;
private Fragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG,"onCreate--执行了");
setContentView(R.layout.activity_main);
fragmentManager=getSupportFragmentManager();
transaction= fragmentManager.beginTransaction();
fragment=new FragmentA();
transaction.add(R.id.fragmenta,fragment,"FragmentA").commit();
fragmentA_Button=(Button) findViewById(R.id.fragmenta_button);
fragmentB_Button=(Button) findViewById(R.id.fragmentb_button);
fragmentA_Button.setOnClickListener(this);
fragmentB_Button.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart--执行了");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume--执行了");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause--执行了");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop--执行了");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy--执行了");
}
@Override
public void onClick(View v) {
transaction= fragmentManager.beginTransaction();
switch (v.getId()){
case R.id.fragmenta_button:
if (fragment!=null)
transaction.hide(fragment);
fragment= fragmentManager.findFragmentByTag("FragmentA");
if (fragment!=null){
transaction.show(fragment);
}
else {
fragment=new FragmentA();
transaction.add(R.id.fragmenta,fragment,"FragmentA").commit();
}
break;
case R.id.fragmentb_button:
if (fragment!=null)
transaction.hide(fragment);
fragment= fragmentManager.findFragmentByTag("FragmentB");
if (fragment!=null){
transaction.show(fragment);
}
else {
fragment=new FragmentB();
transaction.add(R.id.fragmenta,fragment,"FragmentB").commit();
}
break;
}
}
}
这里我们写的比较简单,Mainly to take a look at their execution lifecycle,Here I put solog都打印出来了
Just started runninglog如下:
I/MainActivity: onCreate--执行了
I/FragmentA: onAttach--执行了
I/FragmentA: onCreate--执行了
I/FragmentA: onCreateView--执行了
I/FragmentA: onActivityCreated--执行了
I/FragmentA: onStart--执行了
I/MainActivity: onStart--执行了
I/MainActivity: onResume--执行了
I/FragmentA: onResume--执行了
此时我们点击FragmentB按钮;
I/FragmentB: onAttach--执行了
I/FragmentB: onCreate--执行了
I/FragmentB: onCreateView--执行了
I/FragmentB: onActivityCreated--执行了
I/FragmentB: onStart--执行了
I/FragmentB: onResume--执行了
Then we click repeatedlyFragmentA和FragmentB按钮,发现没有任何log打印,此时证明FragmentA和FragmentB通过hide和showwhen the method is switched,都只会初始化一次,
Below we lookreplace这个方法
replace:
首先replace方法,其实是remove和add方法的组合; remove就是将一个Fragment从FragmentManager中删除,If we switch nextFragment时,上一个Fragment不需要了,可以直接使用replace,If we still need it,API中也提供了相应的方法,That is to join the back stackaddToBackStack()
下面我们把MainActivityChange the code in :
@Override
public void onClick(View v) {
transaction= fragmentManager.beginTransaction();
switch (v.getId()){
case R.id.fragmenta_button:
if (fragment!=null)
transaction.hide(fragment);
fragment= fragmentManager.findFragmentByTag("FragmentA");
if (fragment!=null){
Log.i(TAG,"fragment不为空");
transaction.show(fragment);
}
else {
Log.i(TAG,"fragment为空");
fragment=new FragmentA();
transaction.replace(R.id.fragmenta,fragment,"FragmentA").addToBackStack("FragmentA").commit();
}
break;
case R.id.fragmentb_button:
if (fragment!=null)
transaction.hide(fragment);
fragment= fragmentManager.findFragmentByTag("FragmentB");
if (fragment!=null){
Log.i(TAG,"fragment不为空");
transaction.show(fragment);
}
else {
Log.i(TAG,"fragment为空");
fragment=new FragmentB();
transaction.replace(R.id.fragmenta,fragment,"FragmentB").addToBackStack("FragmentB").commit();
}
break;
}
}
Here we changed itOnClick中的代码,Now let's print it againlog看看:
It is consistent when initialized first:
这里写代码片
此时我们点击FragmentB:
12-18 21:48:14.227 21081-21081/com.shaoen.lenovo.myapplication I/MainActivity: fragment为空
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onPause--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onStop--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onDestroyView--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onAttach--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onCreate--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onCreateView--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onActivityCreated--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onStart--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onResume--执行了
我们发现Fragment调用了destroy方法,此时我们再点击FragmentA:
I/MainActivity: fragment不为空
此时发现FragmentA没有切换过来,这是因为,我们在FragmentManager中找到了FragmentA的实例,但是此时,FragmentAThe interface has been destroyed,So what we see is stillFragmentB,此时我们的OnClick改成如下:
@Override
public void onClick(View v) {
transaction= fragmentManager.beginTransaction();
switch (v.getId()){
case R.id.fragmenta_button:
fragment=new FragmentA();
transaction.replace(R.id.fragmenta,fragment,"FragmentA").addToBackStack("FragmentA").commit();
break;
case R.id.fragmentb_button:
fragment=new FragmentB();
transaction.replace(R.id.fragmenta,fragment,"FragmentB").addToBackStack("FragmentB").commit();
break;
}
}
Then print it againlog,
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onPause--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onStop--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onDestroyView--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onAttach--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onCreate--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onCreateView--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onActivityCreated--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onStart--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onResume--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onPause--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onStop--执行了
12-18 21:48:14.228 21081-21081/com.shaoen.lenovo.myapplication I/FragmentB: onDestroyView--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onAttach--执行了
12-18 21:48:14.229 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onCreate--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onCreateView--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onActivityCreated--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onStart--执行了
12-18 21:48:14.250 21081-21081/com.shaoen.lenovo.myapplication I/FragmentA: onResume--执行了
This time finds every time you switch,都会调用Fragment都会重新调用onCreateView()到onDestroyView()的所有方法,其实就是FragmentThe entire destruction to reconstruction process of the layout layer
注: 当我们进行Fragment嵌套时,If we hit the return key,Don't want to go back to the previous oneFragment,And want to go straight back to the previous one,Or more forwardFragment,我们可以使用FragmentManager.popBackStackImmediate (String tag, int flags)方法,弹出TAG为tag的Fragment,同时把此Fragment以上的Fragment全都弹出(pop back stack,i.e. complete destruction,detach)
有需要文章中完整代码的同学:现在私信发送 “底层源码” 即可免费获取
现在私信发送 “进阶” 还可以获取《更多 Android 源码解析+核心笔记+面试真题》
最后我想说:
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉
边栏推荐
- Technology Sharing | How to use the JSON Schema mode of interface automation testing?
- Arcgis工具箱无法使用,显示“XML包含错误“的解决方法
- “稚晖君”为2022昇腾AI创新大赛打call&nbsp;期待广大开发者加入
- 国内手机厂商曾为它大打出手,如今它却最先垮台……
- navicat 快捷键
- Synchronization lock synchronized traces the source
- 【服务器数据恢复】SAN LUN映射出错导致文件系统数据丢失的数据恢复案例
- AI Knows Everything: Building and Deploying a Sign Language Recognition System from Zero
- Flutter 绘制美不胜收的光影流动效果
- Js fifteen interview questions (with answers)
猜你喜欢
《强化学习周刊》第57期:DL-DRL、FedDRL & Deep VULMAN
Domestic mobile phone manufacturers once fought for it, but now it is the first to collapse...
How to Make Your Company Content GDPR Compliant
Xiaohei leetcode's refreshing rainy day trip, just finished eating Yufei Beef Noodles, Mala Tang and Beer: 112. Path Sum
Flask's routing (app.route) detailed
Flask之路由(app.route)详解
【微服务~Nacos】Nacos之配置中心
Reinforcement Learning Weekly Issue 57: DL-DRL, FedDRL & Deep VULMAN
你真的了解乐观锁和悲观锁吗?
小程序+自定义插件的关键性
随机推荐
NIO Cup 2022 Nioke Summer Multi-School Training Camp 7 CFGJ
宝塔实测-搭建LightPicture开源图床系统
JS Deobfuscation - AST Restoration Case
Xiaohei leetcode's refreshing rainy day trip, just finished eating Yufei Beef Noodles, Mala Tang and Beer: 112. Path Sum
openGauss数据库基本操作(超详细)
Quotefancy ,提供鼓舞人心语录的壁纸网站 - 倾城之链
基于ABP的AppUser对象扩展
random.normal() and random.truncated_normal() in TF
Xiaohei's leetcode journey: 94. Inorder traversal of binary trees (supplementary Morris inorder traversal)
UML类图五种关系的代码实现[通俗易懂]
Liver all night to write a thirty thousand - word all the commands the SQL database, function, speaks clearly explain operators, content is rich, proposal collection + 3 even high praise!
Easyui 表单验证「建议收藏」
面试官:MySQL 中 update 更新,数据与原数据相同时会执行吗?大部分人答不上来!
SQLi-LABS Page-2 (Adv Injections)
Under the NVM node installation;The node environment variable configuration
mysql multi-table left link query
Js fifteen interview questions (with answers)
Technology Sharing | How to use the JSON Schema mode of interface automation testing?
MLOps的演进历程
leetcode 39. 组合总和(完全背包问题)