1. ホーム
  2. アンドロイド

[解決済み】画面の向きが変わってもカスタムビューの状態が失われないようにする方法

2022-04-03 14:49:49

質問

を実装することに成功しました。 onRetainNonConfigurationInstance() 私のメイン Activity 画面の向きが変わっても、特定の重要なコンポーネントを保存・復元できるようにするためです。

しかし、どうやらカスタムビューは向きが変わると一から作り直されているようです。これは理にかなっていますが、私の場合、問題のカスタムビューはX/Yプロットであり、プロットされたポイントはカスタムビューに保存されているので、不便です。

のようなものを実装する狡猾な方法はないのでしょうか? onRetainNonConfigurationInstance() それとも、カスタムビューのメソッドを実装して、カスタムビューの "state" を取得および設定する必要があるのでしょうか?

どのように解決するのですか?

を実装することで、これを行うことができます。 View#onSaveInstanceState View#onRestoreInstanceState を拡張し View.BaseSavedState クラスがあります。

public class CustomView extends View {

  private int stateToSave;

  ...

  @Override
  public Parcelable onSaveInstanceState() {
    //begin boilerplate code that allows parent classes to save state
    Parcelable superState = super.onSaveInstanceState();

    SavedState ss = new SavedState(superState);
    //end

    ss.stateToSave = this.stateToSave;

    return ss;
  }

  @Override
  public void onRestoreInstanceState(Parcelable state) {
    //begin boilerplate code so parent classes can restore state
    if(!(state instanceof SavedState)) {
      super.onRestoreInstanceState(state);
      return;
    }

    SavedState ss = (SavedState)state;
    super.onRestoreInstanceState(ss.getSuperState());
    //end

    this.stateToSave = ss.stateToSave;
  }

  static class SavedState extends BaseSavedState {
    int stateToSave;

    SavedState(Parcelable superState) {
      super(superState);
    }

    private SavedState(Parcel in) {
      super(in);
      this.stateToSave = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
      super.writeToParcel(out, flags);
      out.writeInt(this.stateToSave);
    }

    //required field that makes Parcelables from a Parcel
    public static final Parcelable.Creator<SavedState> CREATOR =
        new Parcelable.Creator<SavedState>() {
          public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
          }
          public SavedState[] newArray(int size) {
            return new SavedState[size];
          }
    };
  }
}

ViewとViewのSavedStateクラスで作業を分担しています。との間で読み書きを行うすべての作業を行う必要があります。 Parcel の中で SavedState クラスを作成します。そして、Viewクラスは、状態メンバを抽出し、クラスを有効な状態に戻すために必要な作業を行うことができます。

注意事項 View#onSavedInstanceStateView#onRestoreInstanceState が自動的に呼び出されます。 View#getId は値 >= 0 を返します。これは、xml で id を与えたり setId を手動で設定します。そうでない場合は View#onSaveInstanceState で取得したParcelに返送されたParcelableを書き込みます。 Activity#onSaveInstanceState で状態を保存し、その後それを読み込んで View#onRestoreInstanceState から Activity#onRestoreInstanceState .

もう一つの簡単な例として CompoundButton