当前位置:网站首页>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 架构师之路还很漫长,与君共勉
边栏推荐
- 发送激活邮件「建议收藏」
- Use convert_to_tensor in Tensorflow to specify the type of data
- Bean life cycle
- Several ways to draw timeline diagrams
- 大型分布式存储方案MinIO介绍,看完你就懂了!
- 腾讯继续挥舞降本增效“大刀”,外包员工免费餐饮福利被砍了
- ACM MM 2022 | Cloud2Sketch: 长空云作画,AI笔生花
- One Pass 2074: [21CSPJ Popularization Group] Candy
- Interpretation of the paper (DropEdge) "DropEdge: Towards Deep Graph Convolutional Networks on Node Classification"
- In-depth analysis of Apache EventMesh cloud-native distributed event-driven architecture
猜你喜欢

Flask之路由(app.route)详解

JSON 基本使用

4D Summary: 38 Knowledge Points of Distributed Systems

MLOps的演进历程

Js fifteen interview questions (with answers)

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!

Sudoku | Backtrack-7

ACM MM 2022 | Cloud2Sketch: Painting with clouds in the sky, AI brush strokes

Presto Event Listener开发

TF generates uniformly distributed tensor
随机推荐
SecureCRT sets the timeout period for automatic disconnection
【微服务~Nacos】Nacos服务提供者和服务消费者
One Pass 2074: [21CSPJ Popularization Group] Candy
五星控股汪建国:以“植物精神”深耕赛道,用“动物精神”推动成长
JS–比想象中简单
在“企业通讯录”的盲区,融云的边界与分寸
基于ABP的AppUser对象扩展
Synchronization lock synchronized traces the source
unit test
Deceptive Dice
Activiti7审批流
navicat 快捷键
阿里云架构师金云龙:基于云XR平台的视觉计算应用部署
openGauss数据库基本操作(超详细)
从产品角度看 L2 应用:为什么说这是一个游乐场?
js数组对象去重
The overall construction process of the Tensorflow model
LeetCode26: remove duplicates in sorted array
Sudoku | Backtrack-7
Technology Sharing | How to use the JSON Schema mode of interface automation testing?