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:
- Override the onSaveInstanceState(Bundle outState) method in Fragment to save the state information to the Bundle object.
- In the Fragment's onCreate() method, check whether the savedInstanceState object is null, and if not, restore the state information from savedInstanceState.
- 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