当前位置:网站首页>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 架构师之路还很漫长,与君共勉

原网站

版权声明
本文为[Android technology stack]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/221/202208091959488465.html