FragmentManager的简单使用

本文查看一下使用fragmentmanager的hide(),show()方法后,fragment执行了什么生命周期
本文创建一个主活动,两个附属的fragment,代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private String tag = "debug";
public Fragment1 fragment1;
    public Fragment2 fragment2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Button button1=findViewById(R.id.button1);
        Button button2=findViewById(R.id.button2);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
        Log.d(tag, "oncreate");

    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button1:
                fragment1=new Fragment1();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment1).commit();
                break;
            case R.id.button2:
                fragment2=new Fragment2();
                getSupportFragmentManager().beginTransaction().hide(fragment1).commit();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment2).commit();
                break;
        }

    }
    @Override
    protected void onStart () {
        Log.d(tag, "onstart");
        super.onStart();
    }

    @Override
    protected void onStop () {
        Log.d(tag, "onstop");
        super.onStop();
    }

    @Override
    protected void onDestroy () {
        Log.d(tag, "ondestroy");
        super.onDestroy();
    }

    @Override
    protected void onPause () {
        Log.d(tag, "onpause");
        super.onPause();
    }

    @Override
    protected void onResume () {
        Log.d(tag, "onresume");
        super.onResume();
    }

}
package com.example.test.fragment;

import android.content.Context;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.example.test.MainActivity;
import com.example.test.R;

public class Fragment1 extends Fragment {
    String tag="debug";
public TextView textView;
public void ran(){
    ;
}
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(tag,"oncreateview1");
        View view=inflater.inflate(R.layout.fragment1,container,false);
textView=view.findViewById(R.id.textView);
        return view;

    }

    @Nullable

    @Override
    public void onAttach(@NonNull Context context) {
        Log.d(tag,"onattachf1");
        super.onAttach(context);

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        Log.d(tag,"oncreatef1");
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        Log.d(tag,"onacitvitycreated");
        super.onActivityCreated(savedInstanceState);

    }

    @Override
    public void onStart() {
        Log.d(tag,"onstartf1");
        super.onStart();
    }

    @Override
    public void onResume() {
        Log.d(tag,"onresumef1");
        super.onResume();
    }

    @Override
    public void onPause() {

        Log.d(tag,"onpausef1");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.d(tag,"onstopf1");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        Log.d(tag,"ondestroyviewf1");
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        Log.d(tag,"ondestroyf1");
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        Log.d(tag,"ondetachf1");
        super.onDetach();
    }
}

package com.example.test.fragment;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.example.test.MainActivity;
import com.example.test.R;

public class Fragment2 extends Fragment implements View.OnClickListener{
    String tag="debug";
    MainActivity mainActivity;
    TextView text;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(tag,"oncreateview2");
        View view=inflater.inflate(R.layout.fragment2,container,false);
      mainActivity= (MainActivity) getActivity();
Button button=view.findViewById(R.id.button);
button.setOnClickListener(this);
 text=view.findViewById(R.id.textView);
     
        return view;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button:
                TextView textView=mainActivity.fragment1.textView;

text.setText(textView.getText().toString());
                break;
        }
    }


    @Nullable

    @Override
    public void onAttach(@NonNull Context context) {
        Log.d(tag,"onattachf2");
        super.onAttach(context);

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        Log.d(tag,"oncreatef2");
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        Log.d(tag,"onacitvitycreatedf2");


        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        Log.d(tag,"onstartf2");
        super.onStart();
    }

    @Override
    public void onResume() {
        Log.d(tag,"onresumef2");
        super.onResume();
    }

    @Override
    public void onPause() {

        Log.d(tag,"onpausef2");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.d(tag,"onstopf2");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        Log.d(tag,"ondestroyviewf2");

        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        Log.d(tag,"ondestroyf2");

        super.onDestroy();
    }

    @Override
    public void onDetach() {
        Log.d(tag,"ondetachf2");
        super.onDetach();
    }


}

他们的布局文件并不需要展示,等下看运行截图就知道了。此处测试的核心代码是:

    fragment2=new Fragment2();
                getSupportFragmentManager().beginTransaction().hide(fragment1).commit();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment2).commit();

然后截图如下,这里的截图已经依次点击了按钮1和按钮2(事务请看MainAcitivity代码),并且点击了获取按钮3(点击按钮3其实就是为了查看这个fragment1的textview会不会因为hide而被销毁,所以此处在fragment2中测试下能不能获取那个textview中的内容,此处显示可以,fragment1的布局文件中textview的内容就是“fragment1中的数据”,也就是没有因为hide而销毁):
在这里插入图片描述生命周期执行情况可以继续证明如下:
在这里插入图片描述
也即是说原来的fragment1还是在运行中的。
下面改变MainActivity中的onClick方法,如下(只改了一点点,表示把fragment1和2加入到返回栈):

  @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button1:
        
                fragment1=new Fragment1();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment1).addToBackStack(null).commit();
                break;
            case R.id.button2:
                fragment2=new Fragment2();
                getSupportFragmentManager().beginTransaction().hide(fragment1).commit();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment2).addToBackStack(null).commit();
                break;
        }

    }

再次运行,结果当然一样,这次操作只是额外manager把他们加入到返回栈而已。下面组另外测试,查看返回键对fragment的影响。按返回键,和平常你测试的时候只有一个MainAcitvity的时候按返回键会直接销毁是一样的。下面进行验证,按一次返回键后,也就是让fragment2出栈,生命周期执行情况为:
在这里插入图片描述
和预料的一样,但是此时fragment1布局中的内容却没有显示,为什么呢?按理此时栈顶是fragment1了啊,其实是我代码写错了,或者没有理解到fragmentmanager加入返回栈的含义,下面看下源码注释是怎么说的:

/**
* Add this transaction to the back stack. This means that the transaction
* will be remembered after it is committed, and will reverse its operation
* when later popped off the stack.
*


* {@link #setReorderingAllowed(boolean)} must be set to true
* in the same transaction as addToBackStack() to allow the pop of that
* transaction to be reordered.
*
* @param name An optional name for this back stack state, or null.
*/

也就是说是把这次事务保存了一下,下次返回是返回到这次事务之前,而一次一次事务是按commit()来计算的,我前面代码那里,用了两个commit(),所以回到的是第二个之前的那个状态,也就是回到还没有加入fragment2之前的状态,所以你按返回键会销毁fragment2。但是这个状态在第一个commit()之后,此时fragment1已经隐藏了,所以就没有显示了。
下面修改代码,正确显示。

 fragment2=new Fragment2();
                getSupportFragmentManager().beginTransaction().hide(fragment1).commit();
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment2).addToBackStack(null).commit();
                break;

修改为

 fragment2=new Fragment2();
                getSupportFragmentManager().beginTransaction().hide(fragment1);
                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment2).addToBackStack(null).commit();

之后重新运行,在按返回键之前,发现显示fragment2的时候发生了重叠,fragment1难道没有隐藏?是的,上面代码还是有问题,因为上面有两次事务,而第一事务没有提交,所以无效。之后按返回键,预测一下结果?是正确的,正确回到fragment1,fragment2被销毁。
下面再改正重叠问题,上面改为:

 fragment2=new Fragment2();

                getSupportFragmentManager().beginTransaction().hide(fragment1).add(R.id.container,fragment2).addToBackStack(null).commit();

或者不想那么长,等价改为:

    fragment2=new Fragment2();
FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.hide(fragment1);
fragmentTransaction.add(R.id.container,fragment2);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

这是因为源码返回值基本都还是一个FragmentTransaction,例如hide():

 @NonNull
    public FragmentTransaction hide(@NonNull Fragment fragment) {
        addOp(new Op(OP_HIDE, fragment));

        return this;
    }

总结:所以hide()和show(),以及加入返回栈都不会影响fragment的生命周期,不会被销毁,replace()方法则另当别论哦。这两个方法我喜欢用来制作一个主页面,点击下面菜单,切换不同的页面,就像QQ那样,刚进入活动时创建这几个fragment页面,然后单机后用hide,show不停切换。
在这里插入图片描述
如果有什么问题,欢迎留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

音程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值