在 Android 中,透明或非全屏的 Activity 不能通过 android:screenOrientation 属性或 setRequestedOrientation() 方法固定屏幕方向。这是因为透明 Activity 的方向依赖于底层 Activity,强制设置可能导致显示异常。
解决方案
1. 移除透明 Activity 的屏幕方向设置
在 AndroidManifest.xml 中,移除透明 Activity 的 android:screenOrientation 属性:
<activity
android:name=".YourTransparentActivity"
android:theme="@style/Theme.Transparent"
<!-- 移除这一行 -->
<!-- android:screenOrientation="portrait" -->
>
</activity>
2. 使用非透明主题
如果你需要固定屏幕方向,确保 Activity 使用的是不透明主题:
<activity
android:name=".YourActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" <!-- 使用不透明主题 -->
>
</activity>
3. 动态检查并设置方向
在代码中动态检查 Activity 是否透明,然后再设置方向:
// 在 Activity 的 onCreate 方法中
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 只在 Activity 不透明时设置方向
if (isActivityOpaque()) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
setContentView(R.layout.activity_main)
}
private fun isActivityOpaque(): Boolean {
try {
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val defaultDisplay = windowManager.defaultDisplay
val metrics = DisplayMetrics()
defaultDisplay.getMetrics(metrics)
val windowAttributes = window.attributes
return windowAttributes.alpha == 1.0f &&
windowAttributes.dimAmount == 0.0f &&
windowAttributes.format == PixelFormat.OPAQUE
} catch (e: Exception) {
return false
}
}
4. 使用透明 DialogFragment 替代
如果你的 Activity 主要用于显示对话框内容,考虑使用 DialogFragment 替代:
总结
- 不要在透明 Activity 中固定方向:移除 AndroidManifest 中的
screenOrientation属性 - 使用 DialogFragment:如果需要透明效果,考虑使用 DialogFragment 替代
- 动态设置方向:在代码中检查 Activity 透明度后再设置方向
- 检查主题配置:确保透明主题正确配置,不包含不兼容的属性
1064

被折叠的 条评论
为什么被折叠?



