[英]How to detect orientation change in layout in Android?
我剛剛實現了一個方向更改功能 - 例如,當布局從縱向變為橫向(反之亦然)時。 如何檢測方向更改事件何時完成。
OrientationEventListener
不起作用。 如何獲得有關布局方向更改事件的通知?
使用 Activity 的onConfigurationChanged方法。 請參閱以下代碼:
@Override
public void onConfigurationChanged(@NotNull 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文件夾中加載布局意味着您有兩個單獨的布局,那么您必須在onConfigurationChanged
方法中創建setContentView
。
@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);
}
}
如果您只有一種布局,則無需在此方法中設置 setContentView。 簡單地
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
只是想向您展示一種在 onConfigurationChanged 后保存所有 Bundle 的方法:
課程結束后創建新的 Bundle:
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 中,您所有的 crated 類都將被保存。
但最好的方法是在你的 AndroidManifest 中添加這個:
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
使用這個方法
@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 ,您需要做兩件事:
Activity 類中的onConfigurationChanged
方法
在清單中指定onConfigurationChanged
方法將處理哪些配置更改
清單片段在上面的答案,而無疑是正確的特定應用程序,明顯屬於,不正是你需要在你的清單中添加,以觸發您的活動課的onConfigurationChanged方法是什么。 即以下清單條目可能不適合您的應用程序。
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
在上面的清單條目中, android:configChanges=""
有各種 Android 操作,它們可以在您的 Activity 生命周期中觸發 onCreate。
這非常重要 -清單中未指定的是觸發您的 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"/>
現在顯然我不想處理所有事情,所以我開始一次消除上述選項。 每次刪除后重新構建和測試我的應用程序。
另一個重點:如果只有一個配置選項被自動處理觸發您的 onCreate(您沒有在上面的清單中列出它),那么它看起來就像onConfigurationChanged
不起作用。 您必須將所有相關的放入您的清單中。
我最終得到了 3 個最初觸發 onCreate 的結果,然后我在 S10+ 上進行了測試,我仍然得到了 onCreate,所以我不得不再次進行消除練習,而且我還需要|screenSize
。 因此,在選擇的平台上進行測試。
<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>
所以我的建議,雖然我確信有人可以在這方面戳破洞:
使用 TOAST 或 LOG 在您的活動類中添加您的onConfigurationChanged
方法,以便您可以看到它何時工作。
將所有可能的配置選項添加到您的清單中。
通過測試您的應用程序來確認您的onConfigurationChanged
方法正在運行。
一次從清單文件中刪除每個配置選項,並在每個選項之后測試您的應用程序。
在盡可能多的設備上進行測試。
不要將我上面的代碼片段復制/粘貼到您的清單文件中。 Android 更新會更改列表,因此請使用彈出的 Android Studio 提示確保您獲得所有提示。
我希望這可以節省一些時間。
我的onConfigurationChanged
方法僅用於以下信息。 onConfigurationChanged
被稱為生命周期后,新的方向是可用的,但在此之前的UI已創建。 因此,我的第一個if
檢查方向是否正常工作,然后第二個嵌套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);
}
}
}
覆蓋活動的方法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();
如果接受的答案對您不起作用,請確保您沒有在清單文件中定義:
android:screenOrientation="portrait"
這是我的情況。
以最簡單的形式實現 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")
}
}
如果其他人像我一樣在這方面花費太長時間 - 它在模擬器上不起作用。 必須是真機。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.