Android Activity内嵌Fragment,当Activity recreate时Fragment被添加多次,造成界面重叠

由于某些原因,例如旋转屏幕,内存不足时,造成Activity被destroy() ,或者切换语言环境时,我们recreate()该Activity。这时,如果在该Activity的onCreate中未区分是create 还是recreate就add Fragment,则会再次add一次该Fragment,造成该Activity中会存在多个相同的Fragment.而导致界面重叠的情况。这种情况下,我们可以在add Fragment时给该Fragment添加一个Tag。在onCreate中addFragment时给该Fragment增加一个Tag。在onCreate方法中添加Fragment,先通过findFragmentByTag的方法来查找该Fragment。在第一次还没添加的时候得到的Fragment为null,如果存在则不用添加该Fragment,如果不存在该Fragment,则添加Fragment。

MainActivity.java 代码如下:

package per.juan.fragmentdome;

import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

public class MainActivity extends AppCompatActivity {
    private ImageView iv_back;

    private Fragment loginPreFragment;
    private Fragment verifyCodeFragment;
    private Fragment accountLoginFragment;

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

    private void initView() {
        iv_back=findViewById(R.id.iv_back);

        iv_back.setImageDrawable(null);
        iv_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showLoginPreFragment();
            }
        });
    }

    /**
     * 事务管理
     */
    private void initDatas() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        //通过TAG查找得到该Fragment,第一次还没添加的时候得到的fragment为null
        loginPreFragment = getSupportFragmentManager().findFragmentByTag(LoginPreFragment.TAG);
        if (loginPreFragment == null) {
            loginPreFragment = new LoginPreFragment();
            transaction.add(R.id.fl_tag_container, loginPreFragment, LoginPreFragment.TAG);
        }

        verifyCodeFragment = getSupportFragmentManager().findFragmentByTag(VerifyCodeFragment.TAG);
        if (verifyCodeFragment == null) {
            verifyCodeFragment = new VerifyCodeFragment();
            transaction.add(R.id.fl_tag_container, verifyCodeFragment, VerifyCodeFragment.TAG);
        }

        accountLoginFragment = getSupportFragmentManager().findFragmentByTag(AccountLoginFragment.TAG);
        if (accountLoginFragment == null) {
            accountLoginFragment = new AccountLoginFragment();
            transaction.add(R.id.fl_tag_container, accountLoginFragment, AccountLoginFragment.TAG);
        }

        transaction.show(loginPreFragment).hide(verifyCodeFragment).hide(accountLoginFragment);//默认显示第一个Frament
        transaction.commit();
    }

    /**
     * 显示手机号预注册界面
     */
    private void showLoginPreFragment() {
        getSupportFragmentManager()
                .beginTransaction()
                .show(loginPreFragment).hide(verifyCodeFragment).hide(accountLoginFragment).commit();
        iv_back.setImageDrawable(null);
    }

    /**
     * 显示验证码校验页
     */
    public void showVerifyCodeFragment() {
        getSupportFragmentManager()
                .beginTransaction()
                .show(verifyCodeFragment).hide(loginPreFragment).hide(accountLoginFragment).commit();
        iv_back.setImageDrawable(getResources().getDrawable(R.drawable.icon_back));
    }

    /**
     * 显示账号登录页
     */
    public void showAccountLoginFragment() {
        getSupportFragmentManager()
                .beginTransaction()
                .show(accountLoginFragment).hide(loginPreFragment).hide(verifyCodeFragment).commit();
        iv_back.setImageDrawable(getResources().getDrawable(R.drawable.icon_back));
    }

    @Override
    public void onBackPressed() {
        if (iv_back.getDrawable() != null) {
            showLoginPreFragment();
        } else {
            super.onBackPressed();
        }
    }
}

由于Fragment还没有添加进来,通过Fragment.TAG是找不到Fragment的,所以此时fragment的值为null。这时要新建Fragment并附带Fragment.TAG进行add操作,这时也就将fragment与Fragment.TAG绑定在一起了。这时候如果旋转屏幕、进入后台之后再次启动(内存不够)或者执行recreate()等情况,重新执行create时,通过Fragment.TAG就可以找到不为空的fragment,,此时就不会重建Fragment了。

LoginPreFragment.java 代码:

package per.juan.fragmentdome;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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

/**
 * Created by juan on 2019/09/03.
 */
public class LoginPreFragment extends Fragment {
    public static final String TAG = "loginPreFragment";

    public Activity mActivity;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_pre_login, container, false);
        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.iv_logo).setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                getMainActivity().recreate();
                return true;
            }
        });

        view.findViewById(R.id.btn_verify_code).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getMainActivity().showVerifyCodeFragment();
            }
        });

        view.findViewById(R.id.btn_account_login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getMainActivity().showAccountLoginFragment();
            }
        });
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.mActivity = (Activity) context;
    }

    private MainActivity getMainActivity() {
        return ((MainActivity) mActivity);
    }
}

好了,本篇文章就这样啦,存在不到位的地方还望指导,感谢~
源码下载

你可能感兴趣的:(【Android,基础】)