Prefacio:
El problema de que Fragment retroceda y cargue y ejecute repetidamente onCreateView generalmente se debe a la secuencia de invocación y al uso inadecuado de los métodos del ciclo de vida de Fragment.
1, método onSaveInstanceState()
Una solución es usar el método onSaveInstanceState() en el Fragmento para guardar el estado del Fragmento y restaurar el estado en el método onCreate() para evitar la ejecución repetida de onCreateView(). Los pasos específicos son los siguientes:
- Anule el método onSaveInstanceState(Bundle outState) en Fragment para guardar la información de estado en el objeto Bundle.
- En el método onCreate() de Fragment, verifique si el objeto SavedInstanceState es nulo y, de lo contrario, restaure la información de estado de SavedInstanceState.
- En el método onCreateView(), juzgue si la vista de la interfaz de usuario ya existe. Si ya existe, no necesita volver a crearla, solo devuelva la vista almacenada en caché directamente.
El código de ejemplo es el siguiente:
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 el método replace() de Fragment para saltar en lugar del método add()
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, new MyFragment());
transaction.addToBackStack(null);
transaction.commit();
3. Utilice el logotipo: hasInitialized
Al realizar operaciones como la inicialización de datos y la actualización de la interfaz en onCreateView de Fragment, es necesario determinar si la operación relevante se ha realizado antes. Si la operación ya se ha realizado, no es necesario volver a ejecutarla.
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, a juzgar si ya existe la vista raíz, este método es un poco similar al tercero y al primero.
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;
}
Resumir:
Personalmente, la solución más simple es 3, 4, el método a elegir depende de la situación real.
Nota: Solo es aplicable al proceso de evaluación de volver a retroceder con la tecla de retorno. Recuerde, la interfaz que se ha abierto repetidamente parece no ser válida.