方向変更機能を実装しました-たとえば、レイアウトが縦から横に(またはその逆に)変更された場合。方向変更イベントがいつ終了したかをどのように検出できますか?
OrientationEventListener動作しませんでした。レイアウト方向変更イベントに関する通知を受け取るにはどうすればよいですか?
方向変更機能を実装しました-たとえば、レイアウトが縦から横に(またはその逆に)変更された場合。方向変更イベントがいつ終了したかをどのように検出できますか?
OrientationEventListener動作しませんでした。レイアウト方向変更イベントに関する通知を受け取るにはどうすればよいですか?
回答:
Activity のonConfigurationChangedメソッドを使用します。次のコードを参照してください。
@Override
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();
}
}
また、適切な編集も必要です android:configChangesを含めるマニフェストファイルの要素 以下のコードをご覧ください。
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
注: Android 3.2(APIレベル13)以降では、デバイスを縦向きと横向きに切り替えると、「画面サイズ」も変化します。したがって、APIレベル13以降の開発時に方向の変更によるランタイムの再起動を防止する場合は、APIレベル13以降のandroid:configChanges = "orientation | screenSize"を宣言する必要があります。
これがあなたを助けることを願っています... :)
レイアウトをlayout-landフォルダーにロードするには、2つの個別のレイアウトがありsetContentView、onConfigurationChangedメソッドで作成する必要があります。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.yourxmlinlayout-land);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.yourxmlinlayoutfolder);
}
}
レイアウトが1つしかない場合は、このメソッドでsetContentViewを作成する必要はありません。単に
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
onConfigurationChanged(Configuration newConfig)(この回答のように)メソッドを実装しましたが、自分で処理するのではなく、ブールフラグを設定してrecreate()メソッドを呼び出し、Androidが通常の方法でアクティビティを再作成するようにしました。
recreate()方法の1つの問題は、画面が一瞬黒く点滅することです。このため、別のアプローチを使用しました:(1)画面幅をに保存しonCreate(...)、(2)保存された画面幅を、アクティビティが終了しているときのライフサイクルメソッド(たとえばonSaveInstanceState(...))で現在の画面幅と比較します。
onConfigurationChangedの後ですべてのバンドルを保存する方法を示したかっただけです。
クラスの直後に新しいバンドルを作成します。
public class MainActivity extends Activity {
Bundle newBundy = new Bundle();
次に、「protected void onCreate」の後にこれを追加します。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
onSaveInstanceState(newBundy);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
onSaveInstanceState(newBundy);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle("newBundy", newBundy);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getBundle("newBundy");
}
これを追加すると、すべてのクレートされたクラスがMainActivityに保存されます。
しかし、最善の方法は、これをAndroidManifestに追加することです。
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
onConfigurationChanged()するとインスタンスの状態が変更されてもインスタンス状態が破棄されないため、保存する必要はありません。アクティビティライフサイクルの他のイベントのために保存することもできますが、わかりません。
この方法を使用
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
{
Toast.makeText(getActivity(),"PORTRAIT",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on PORTRAIT MODE
}
else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Toast.makeText(getActivity(),"LANDSCAPE",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on LANDSCAPE MODE
}
}
そして、あなたのAndroidmainfest.xmlにこれを追加することを忘れないでください
android:configChanges="orientation|screenSize"
このような
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:configChanges="orientation|screenSize">
</activity>
アクティビティのメソッドonConfigurationChangedをオーバーライドする
上記の説明のように、実際に一部のユーザーに関係する別の代替案を提案したいのですが
android:configChanges="orientation|keyboardHidden"
挿入するレイアウトを明示的に宣言することを意味します。
layout-landとlayoutフォルダーのおかげで自動注入を維持したい場合に備えて。これをonCreateに追加するだけです。
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
getSupportActionBar().hide();
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
getSupportActionBar().show();
}
ここでは、電話の向きに応じてアクションバーを表示するかどうかを示します
OrientationEventListenerクラスのインスタンスを作成して有効にします。
OrientationEventListener mOrientationEventListener = new OrientationEventListener(YourActivity.this) {
@Override
public void onOrientationChanged(int orientation) {
Log.d(TAG,"orientation = " + orientation);
}
};
if (mOrientationEventListener.canDetectOrientation())
mOrientationEventListener.enable();
上記で指定されていないため、これが一部の新しい開発者に役立つ場合。非常に明確にするために:
onConfigurationChangedを使用する場合、次の 2つが必要です。
onConfigurationChangedアクティビティクラスのメソッド
設定の変更は、あなたのマニフェストに指定によって処理されますあなたのonConfigurationChanged方法
マニフェストが属する特定のアプリケーションのための正しいは間違いないが、ある一方、上記の回答ではマニフェストスニペット、NOTあなたが追加する必要があるかを正確にあなたのマニフェストあなたのアクティビティクラスでonConfigurationChangedメソッドをトリガーします。つまり、以下のマニフェストエントリがアプリに対して正しくない場合があります。
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
上記のマニフェストエントリにandroid:configChanges=""は、アクティビティのライフサイクルでonCreateをトリガーできるさまざまなAndroidアクションがあります。
これは非常に重要である- マニフェストに指定されていないものは、あなたのonCreateをトリガーするものですし、マニフェストに指定されたものは、あなたの引き金ものですonConfigurationChanged方法あなたのアクティビティクラスでは。
したがって、自分で処理するために必要な構成変更を特定する必要があります。私のようなAndroid Encyclopedically Challengedの場合、私はAndroid Studioのクイックヒントポップアウトを使用し、ほとんどすべての可能な構成オプションに追加しました。これらすべてをリストすると、基本的にはすべてを処理し、構成のためにonCreateが呼び出されることはないと述べました。
<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>
今は明らかにすべてを処理したくないので、上記のオプションを1つずつ削除し始めました。削除するたびにアプリを再構築してテストします。
別の重要なポイント:onCreateをトリガーする自動的に処理される構成オプションが1つしかない場合(上記のマニフェストにリストされていない場合)、機能してonConfigurationChangedいないように見えます。関連するすべてのものをマニフェストに入れる必要があります。
元々onCreateをトリガーしていた3つで終了し、その後S10 +でテストしましたが、それでもonCreateを取得していたため、消去演習を再度行う必要があり、も必要でした|screenSize。したがって、選択したプラットフォームでテストします。
<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>
だから私の提案、誰かがこれに穴を開けることができると確信していますが:
onConfigurationChangedTOASTまたはLOGを使用してアクティビティクラスにメソッドを追加すると、いつ動作するかを確認できます。
可能なすべての構成オプションをマニフェストに追加します。
onConfigurationChangedアプリをテストして、メソッドが機能していることを確認します。
マニフェストファイルから各構成オプションを1つずつ削除し、それぞれの後にアプリをテストします。
できるだけ多くのデバイスでテストします。
上記のスニペットをマニフェストファイルにコピー/貼り付けしないでください。Androidのアップデートによりリストが変更されるため、ポップアウトのAndroid Studioのヒントを使用して、すべてを入手してください。
これが誰かの時間の節約になることを願っています。
onConfigurationChanged以下の情報のための私の方法。onConfigurationChangedライフサイクルで呼び出された後、新たな向きが利用可能ですが、前の UIが再作成されました。したがって、最初ifに向きを確認する最初の動作が正しく機能し、次に2番目のネストifがUI ImageViewの可視性を確認するために正しく動作します。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
}
}
最も単純な形式でのKotilin実装の場合-画面が縦向きから横向きに変化したときにのみ発火します---重力センサー値にタブで移動する必要があるデバイスのフリップ検出(180度)が必要な場合は横向き
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rotation = windowManager.defaultDisplay.rotation
when (rotation) {
0 -> Log.d(TAG,"at zero degree")
1 -> Log.d(TAG,"at 270 degree")
2 -> Log.d(TAG,"at 180 degree")
3 -> Log.d(TAG,"at 90 degree")
}
}