Android's Fragment jumps back to the four solutions for repeated loading and repeated execution of onCreateView

Foreword: 

The problem of Fragment jumping back and repeatedly loading and repeatedly executing onCreateView is usually caused by the invocation sequence and improper use of Fragment lifecycle methods.

1,onSaveInstanceState() method

One solution is to use the onSaveInstanceState() method in the Fragment to save the state of the Fragment, and restore the state in the onCreate() method to avoid repeated execution of onCreateView(). Specific steps are as follows:

  1. Override the onSaveInstanceState(Bundle outState) method in Fragment to save the state information to the Bundle object.
  2. In the Fragment's onCreate() method, check whether the savedInstanceState object is null, and if not, restore the state information from savedInstanceState.
  3. In the onCreateView() method, judge whether the UI view already exists. If it already exists, you don't need to recreate it, just return the cached view directly.

The sample code is as follows:

public class MyFragment extends Fragment {
    private View rootView;
    private boolean isViewCreated = false;
    private boolean isDataLoaded = false;

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("isDataLoaded", isDataLoaded);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            isDataLoaded = savedInstanceState.getBoolean("isDataLoaded");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.fragment_my, container, false);
            isViewCreated = true;
        } else {
            isViewCreated = false;
            ViewGroup parent = (ViewGroup) rootView.getParent();
            if (parent != null) {
                parent.removeView(rootView);
            }
        }

        if (!isDataLoaded) {
            loadData();
        }

        return rootView;
    }

    private void loadData() {
        // 加载数据的操作
        isDataLoaded = true;
    }
}

2. Use the replace() method of Fragment to jump instead of the add() method

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, new MyFragment());
transaction.addToBackStack(null);
transaction.commit();

3. Use the logo: hasInitialized

When performing operations such as data initialization and interface update in Fragment's onCreateView, it is necessary to determine whether the relevant operation has been performed before. If the operation has already been performed, it does not need to be executed again.

public class MyFragment extends Fragment {
    private boolean hasInitialized = false;
    private TextView mTextView;
    private View mView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (!hasInitialized) {
            mView = inflater.inflate(R.layout.fragment_my, container, false);
            mTextView = (TextView) mView.findViewById(R.id.tv_content);
            initData();
            hasInitialized = true;
        }
        return mView;
    }

    private void initData() {
        // 如果之前没有初始化过数据,则初始化并显示
        // 如果已经初始化过了,则不需要再次初始化
        if (TextUtils.isEmpty(mTextView.getText())) {
            mTextView.setText("这是我的Fragment");
        }
    }
}

4, Judging whether the rootview already exists, this method is a little similar to the third and first.

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
        if (null != view) {  
            ViewGroup parent = (ViewGroup) view.getParent();  
            if (null != parent) {  
                parent.removeView(view);  
            }  
        } else {  
            view = inflater.inflate(R.layout.fragment_main, container, false);  
            initView(view);// 控件初始化  
        }  
        return view;  
  
    } 

Summarize:

Personally, the simplest solution is 3, 4, which method to choose depends on the actual situation.

Note: It is only applicable to the judging process of re-rolling back by the return key. Remember, the interface that has been opened repeatedly seems to be invalid

Guess you like

Origin blog.csdn.net/wh445306/article/details/130866946