1444

私の Android アプリケーションでは、デバイスを回転させる (キーボードをスライドさせる) と、Activity再起動されます (onCreate呼び出されます)。onCreateさて、これはおそらく本来あるべき姿ですが、メソッドで多くの初期設定を行うため、次のいずれかが必要です。

  1. すべての初期設定を別の関数に入れて、デバイスのローテーションまたは
  2. 再度呼び出されないようonCreateにして、レイアウトを調整するか、
  3. onCreate呼び出されないように、アプリを縦向きに制限します。
4

34 に答える 34

990

アプリケーション クラスの使用

初期化で行っていることによっては、拡張する新しいクラスを作成しApplication、初期化コードをそのクラス内のオーバーライドされたonCreateメソッドに移動することを検討できます。

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

アプリケーション クラス内のonCreateは、アプリケーション全体が作成されたときにのみ呼び出されるため、向きやキーボードの可視性の変更によってアクティビティが再開されることはありません。

このクラスのインスタンスをシングルトンとして公開し、ゲッターとセッターを使用して初期化するアプリケーション変数を公開することをお勧めします。

注: 新しい Application クラスを登録して使用するには、マニフェストで新しい Application クラスの名前を指定する必要があります。

<application
    android:name="com.you.yourapp.MyApplicationClass"

構成変更への対応 [更新: これは API 13 以降非推奨です。推奨される代替案を参照してください]

さらに別の方法として、再起動の原因となるイベント (向きやキーボードの可視性の変更など) をアプリケーションでリッスンし、Activity 内で処理することもできます。

android:configChangesアクティビティのマニフェスト ノードにノードを追加することから始めます。

 <activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

またはAndroid 3.2 (API レベル 13) 以降の場合:

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:label="@string/app_name">

次に、Activity 内でonConfigurationChangedメソッドをオーバーライドして呼び出しsetContentView、GUI レイアウトを新しい向きで強制的に再実行します。

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}
于 2009-01-19T08:47:59.960 に答える
192

Android 3.2 以降のアップデート:

注意: Android 3.2 (API レベル 13) から、端末の縦向きと横向きを切り替えると、「画面サイズ」も変わります。"screenSize"したがって、API レベル 13 以降 (minSdkVersion および targetSdkVersion 属性で宣言) 向けに開発する際に方向の変更によるランタイムの再起動を防止する場合は、値に加えて値を含める必要があり"orientation"ます。つまり、宣言する必要がありますandroid:configChanges="orientation|screenSize"。ただし、アプリケーションが API レベル 12 以下をターゲットにしている場合、アクティビティは常にこの構成変更自体を処理します (Android 3.2 以降のデバイスで実行されている場合でも、この構成変更によってアクティビティが再開されることはありません)。

于 2012-03-03T21:56:40.480 に答える
135

onCreate()が発生するのを完全に止めようとする代わりにBundle savedInstanceState、イベントに渡される をチェックして、それが null かどうかを確認してみてください。

たとえば、Activity向きが変わるたびにではなく、 が実際に作成されたときに実行するロジックがあるonCreate()場合、savedInstanceStateが null の場合にのみ でそのロジックを実行します。

それ以外の場合は、向きに合わせてレイアウトを適切に再描画する必要があります。

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

これが究極の答えかどうかはわかりませんが、私にとってはうまくいきます。

于 2012-08-04T21:04:23.783 に答える
104

私がしたこと...

マニフェストのアクティビティセクションに、次のように追加しました。

android:configChanges="keyboardHidden|orientation"

アクティビティのコードで、実装されています:

//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
    //get views from ID's
    this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);

    //etc... hook up click listeners, whatever you need from the Views
}

//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    InitializeUI();
}

//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);

    InitializeUI();
}
于 2011-01-04T01:26:44.193 に答える
72

あなたが説明するのはデフォルトの動作です。以下を追加して、これらのイベントを自分で検出して処理する必要があります。

android:configChanges

マニフェストに追加してから、処理する変更を追加します。したがって、オリエンテーションには、次を使用します。

android:configChanges="orientation"

キーボードを開いたり閉じたりするには、次を使用します。

android:configChanges="keyboardHidden"

両方を処理したい場合は、次のようなパイプ コマンドでそれらを分離できます。

android:configChanges="keyboardHidden|orientation"

これにより、呼び出したアクティビティで onConfigurationChanged メソッドがトリガーされます。メソッドをオーバーライドすると、新しい値を渡すことができます。

お役に立てれば。

于 2009-01-19T02:28:45.933 に答える
51

私はちょうどこの伝承を発見しました:

方向の変更によってアクティビティを維持し、それを介して処理するためにonConfigurationChanged上記のドキュメントコード サンプルでは、​​マニフェスト ファイルで次のことを提案しています。

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

これには、常に機能するという追加の利点があります。

おまけの伝承は、 を省略すると論理的に見えるかもしれませんが、keyboardHiddenエミュレーターでエラーが発生することです (少なくとも Android 2.1 の場合) 。orientationOnCreateonConfigurationChangedOnCreate

デバイスでの失敗は見たことがありませんが、エミュレーターでの失敗については聞いたことがあります。したがって、文書化する価値があります。

于 2010-12-22T21:50:52.807 に答える
40

onRetainNonConfigurationInstance()また、向きの変更を超えてデータを永続化するAndroidプラットフォームの方法を使用することを検討することもできます getLastNonConfigurationInstance()

これにより、サーバーフェッチから取得した情報onCreateや、それ以降に計算された情報など、構成の変更を超えてデータを保持できます。また、AndroidはActivity、現在使用中の方向にxmlファイルを使用して再レイアウトすることもできます。 。

ここまたはここを参照してください。

これらのメソッドは現在非推奨になっていることに注意してください(ただし、上記のソリューションのほとんどが示唆しているように、向きの変更を自分で処理するよりも柔軟性がありますFragments)。setRetainInstance(true)Fragment

于 2011-09-22T03:03:00.180 に答える
34

このアプローチは便利ですが、フラグメントを使用する場合は不完全です。

フラグメントは通常、構成の変更時に再作成されます。これが発生したくない場合は、

setRetainInstance(true);フラグメントのコンストラクターで

これにより、構成の変更中にフラグメントが保持されます。

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)

于 2012-09-21T09:09:25.313 に答える
21

AndroidのonCreateを変更しても、メソッドは引き続き呼び出されます。orientationしたがって、すべての重い機能をこのメソッドに移動しても、役に立ちません

于 2010-01-21T10:40:44.900 に答える
21

<activity>のタグ内に以下のコードを挿入しますManifest.xml

android:configChanges="screenLayout|screenSize|orientation"
于 2014-08-21T11:55:28.200 に答える
20

次の手順を実行するだけで非常に簡単です。

<activity
    android:name=".Test"
    android:configChanges="orientation|screenSize"
    android:screenOrientation="landscape" >
</activity>

これは私のために働く:

注:オリエンテーションは要件によって異なります

于 2015-12-14T06:39:04.617 に答える
19
 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

マニフェストのどの部分が「電話しないでください」と言っていますonCreate()か?

また、グーグルのドキュメントは使用を避けるように言ってandroid:configChangesいます(最後の手段としてを除いて)...しかし、彼らが提案する代替方法はすべて使用しますandroid:configChanges

エミュレーターが常にonCreate()ローテーションを呼び出すのは私の経験です。
しかし、私が同じコードを実行している1〜2台のデバイスは...そうではありません。(なぜ違いがあるのか​​わかりません。)

于 2012-02-01T15:55:53.810 に答える
17

Android マニフェストに加える変更は次のとおりです。

android:configChanges="keyboardHidden|orientation" 

アクティビティ内で行われる追加は次のとおりです。

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
于 2011-11-11T12:20:03.190 に答える
16

これを行うにはいくつかの方法があります。

アクティビティの状態を保存

アクティビティの状態を に保存できますonSaveInstanceState

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

を使用しbundleて状態を復元します。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}

向きの変更を自分で処理する

もう 1 つの方法は、向きの変更を自分で処理することです。しかし、これは良い習慣とは見なされません。

これをマニフェスト ファイルに追加します。

android:configChanges="keyboardHidden|orientation"

Android 3.2 以降の場合:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

回転を制限する

回転を避けるために、アクティビティを縦向きまたは横向きモードに限定することもできます。

これをマニフェスト ファイルのアクティビティ タグに追加します。

        android:screenOrientation="portrait"

または、これをプログラムでアクティビティに実装します。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
于 2016-01-07T18:55:10.533 に答える
12

私がこれを行うために見つけた方法は、onRestoreInstanceStateonSaveInstanceStateイベントを使用して に何かを保存することBundleです (変数を保存する必要がない場合でも、そこに何かを入れて がBundle空にならないようにしてください)。次に、onCreateメソッドで が空かどうかを確認し、Bundle空である場合は初期化を行い、そうでない場合はそれを実行します。

于 2012-12-21T20:15:08.237 に答える
12

「Android のやり方」ではありませんが、向きの変更を自分で処理し、変更された向きを考慮してビュー内でウィジェットを再配置するだけで、非常に良い結果が得られました。ビューを保存して復元する必要がないため、これは他のどのアプローチよりも高速です。また、再配置されたウィジェットはまったく同じウィジェットであり、移動またはサイズ変更されただけであるため、ユーザーによりシームレスなエクスペリエンスを提供します。モデルの状態だけでなく、ビューの状態もこの方法で保持できます。

RelativeLayoutときどき向きを変える必要があるビューに適している場合があります。子ウィジェットごとに、縦向きのレイアウト パラメータのセットと横向きのレイアウト パラメータのセットを提供するだけで、それぞれに異なる相対的な配置ルールが適用されます。次に、メソッドで、適切なメソッドを各子onConfigurationChanged()の呼び出しに渡します。setLayoutParams()子コントロール自体を内部的に再配置する必要がある場合は、その子のメソッドを呼び出して再配置を実行します。その子は、同様に、内部の方向変更などを必要とする子コントロールのメソッドを呼び出します。

于 2012-03-16T09:13:20.680 に答える
8

onSavedInstanceState メソッドを使用して、すべての値をそのパラメーターに格納する必要がありますが、それはバンドルです

@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outPersistentState.putBoolean("key",value);
    }

と使用

@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        savedInstanceState.getBoolean("key");
    } 

オブジェクトを表示する値を取得して設定するには、画面の回転を処理します

于 2016-12-07T10:23:07.427 に答える
7

注:将来誰かが私と同じ問題に直面した場合、この回答を投稿します。私にとって、次の行は十分ではありませんでした:

android:configChanges="orientation"

画面を回転させたところ、メソッド onConfigurationChanged(Configuration newConfig) が呼び出されませんでした。

解決策:問題が向きに関係していたとしても、「screenSize」も追加する必要がありました。そのため、AndroidManifest.xml ファイルに次のように追加します。

android:configChanges="keyboardHidden|orientation|screenSize"

次に、メソッドを実装しますonConfigurationChanged(Configuration newConfig)

于 2014-04-24T14:40:42.850 に答える
4

以下のコードを in に入れActivityますAndroid Manifest

android:configChanges="orientation"

方向を変更しても、アクティビティは再開されません。

于 2013-07-29T07:09:51.510 に答える
4

で画面の向き (横または縦) を修正します。AndroidManifest.xml

android:screenOrientation="portrait"またandroid:screenOrientation="landscape"

このため、onResume()メソッドは呼び出されません。

于 2013-02-15T11:14:06.350 に答える
1

これを行うには複数の方法があります。

向きの変更を自分で処理する

もう 1 つの方法は、向きの変更を自分で処理することです。しかし、これは良い習慣とは見なされません。

これをマニフェスト ファイルに追加します。

android:configChanges="keyboardHidden|orientation"

Android 3.2 以降の場合:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

または回転を制限する

回転を避けるために、アクティビティを縦向きまたは横向きモードに限定することもできます。

これをマニフェスト ファイルのアクティビティ タグに追加します。

android:screenOrientation="ポートレート"

または、これをプログラムでアクティビティに実装します。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

またはアクティビティの状態を保存

アクティビティの状態は onSaveInstanceState に保存できます。

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

次に、バンドルを使用して状態を復元します。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}
于 2020-02-11T10:46:50.850 に答える