Fragment de Android salta hacia atrás y carga repetidamente cuatro soluciones para ejecutar repetidamente onCreateView

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:

  1. Anule el método onSaveInstanceState(Bundle outState) en Fragment para guardar la información de estado en el objeto Bundle.
  2. 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.
  3. 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.

Supongo que te gusta

Origin blog.csdn.net/wh445306/article/details/130866946
Recomendado
Clasificación