Android の Fragment は、戻って 4 つのソリューションを繰り返しロードし、onCreateView を繰り返し実行します。

序文: 

Fragment が戻って繰り返し読み込み、onCreateView を繰り返し実行する問題は、通常、呼び出しシーケンスと Fragment ライフサイクル メソッドの不適切な使用によって発生します。

1,onSaveInstanceState()方法

1 つの解決策は、フラグメントの onSaveInstanceState() メソッドを使用してフラグメントの状態を保存し、onCreate() メソッドで状態を復元して、onCreateView() の繰り返し実行を避けることです。具体的な手順は次のとおりです。

  1. Fragment の onSaveInstanceState(Bundle outState) メソッドをオーバーライドして、状態情報を Bundle オブジェクトに保存します。
  2. フラグメントの onCreate() メソッドで、savedInstanceState オブジェクトが null かどうかを確認し、null でない場合は、savedInstanceState から状態情報を復元します。
  3. onCreateView() メソッドでは、UI ビューが既に存在するかどうかを判断し、既に存在する場合は再作成する必要はなく、キャッシュされたビューを直接返すだけです。

サンプルコードは次のとおりです。

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. add() メソッドの代わりに、Fragment の replace() メソッドを使用してジャンプします。

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

3. ロゴを使用します: hasInitialized

FragmentのonCreateViewでデータの初期化やインターフェースの更新などの操作を行う場合、当該操作が以前に行われたかどうかを判断する必要がありますが、既に行われている場合は再度実行する必要はありません。

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. ルートビューが既に存在するかどうかを判断するこの方法は、3 番目と 1 番目の方法と少し似ています。

    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;  
  
    } 

要約:

個人的には、最も簡単な解決策は 3、4 ですが、どの方法を選択するかは実際の状況によって異なります。

注: これは、戻るキーと戻るキーの判定プロセスにのみ適用されます。繰り返し開かれたインターフェースは無効であるように見えることに注意してください。

おすすめ

転載: blog.csdn.net/wh445306/article/details/130866946