[解決済み] フラグメントのインスタンス状態をバックスタックに正しく保存する方法は?
質問
SOで似たような質問をたくさん見つけたのですが、残念ながら私の要求を満たす回答がありません。
縦長と横長でレイアウトを変えており、バックスタックを使用しているのですが、どちらも
setRetainState()
と設定変更ルーチンを使ったトリックがあります。
ある情報をTextViewsでユーザーに表示するのですが、デフォルトのハンドラでは保存されないのです。アクティビティだけを使ってアプリケーションを書く場合、以下のようにするとうまくいきました。
TextView vstup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.whatever);
vstup = (TextView)findViewById(R.id.whatever);
/* (...) */
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putCharSequence(App.VSTUP, vstup.getText());
}
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
vstup.setText(state.getCharSequence(App.VSTUP));
}
と
Fragment
の場合、これは非常に特殊な状況でのみ機能します。具体的に言うと、恐ろしいほど壊れるのは、フラグメントを置き換えてバックスタックに入れ、新しいフラグメントが表示されている間に画面を回転させる場合です。私が理解したところでは、古いフラグメントは
onSaveInstanceState()
にリンクしたままです。
Activity
で、このメソッドは後でその
View
はもう存在しないので、私の任意の
TextView
の結果は
NullPointerException
.
また、私の場合は、参照を維持することで
TextViews
を使うのは、あまり良いアイデアではありません。
Fragment
の場合はOKだったとしても
Activity
's. その場合
onSaveInstanceState()
は実際に状態を保存していますが、画面を回転させると問題が再発します。
2回
フラグメントが非表示の場合、その
onCreateView()
は新しいインスタンスでは呼び出されません。
で状態を保存することを考えました。
onDestroyView()
をいくつかの
Bundle
-タイプのクラス・メンバー要素 (実際にはもっと多くのデータがあり、1つの
TextView
を保存し
その
で
onSaveInstanceState()
が、他にも欠点がある。主に、もしフラグメント
は
現在表示されている2つの関数の呼び出し順が逆になっているので、2種類の状況を考慮する必要がありますね。もっとすっきりした正しい解決策があるはずです
どのように解決するのですか?
のインスタンス状態を正しく保存するために
Fragment
は、次のようにします。
1.
フラグメントの中で、インスタンスの状態を保存するために
onSaveInstanceState()
でリストアし
onActivityCreated()
:
class MyFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...
if (savedInstanceState != null) {
//Restore the fragment's state here
}
}
...
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's state here
}
}
2.
そして
重要ポイント
アクティビティでは、フラグメントのインスタンスを
onSaveInstanceState()
で復元し
onCreate()
.
class MyActivity extends Activity {
private MyFragment
public void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
//Restore the fragment's instance
mMyFragment = getSupportFragmentManager().getFragment(savedInstanceState, "myFragmentName");
...
}
...
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's instance
getSupportFragmentManager().putFragment(outState, "myFragmentName", mMyFragment);
}
}
関連
-
Android.mk:7: *** セパレータがありません。
-
AndroidStudio3.0 Error:Execution failed for task ':app:processDebugResources'.
-
Android TextViewにandroid:ellipsize=endのバグがある。
-
ConstraintLayoutのいくつかのプロパティの概要(RelativeLayoutの強化版、LinearLayoutの比例プロパティを含む、階層ツールの削減)。
-
AndroidでListViewを使ってカスタムテーブルを描画する
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] FragmentのsetRetainInstance(boolean)を理解する。
-
[解決済み】プログレスダイアログとバックグラウンドスレッドがアクティブなときに、画面の向きが変わるのをどう処理するか?
-
[解決済み】フラグメントを使用してバックスタックをクリアする
-
[解決済み] バックスタックに追加されたフラグメントの状態を維持するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
IllegalStateException。ArrayAdapter は、リソース ID が TextView である必要があります。
-
アンドロイドスタジオでJunitのエラー問題を解決する
-
telnet'が内部コマンドまたは外部コマンドとして認識されない 解決方法
-
ライブラリをモジュールとしてインポートする際にエラーが発生しました。Error:A problem occurred configuring project ':library'.
-
プロセス 'command 'F:\sdkbuild-tools', 26.0.2 AAAPT.exe' finished with non-zero exit value 1
-
GoogleMapと連携し、位置情報の取得が可能
-
repo: コマンドが見つかりません
-
アンドロイドにおけるトークンの利用
-
[解決済み] ListViewに戻ったときのスクロール位置の維持/保存/復元
-
[解決済み] android fragment- 別のフラグメントがプッシュされたときに、フラグメント内のビューの状態を保存する方法