我的活动的 onCreate 中有一个 OrientationEventListener,如果用户旋转他的手机,它会执行一个操作。我还有一个按钮,如果单击该按钮,则会旋转屏幕布局,而无需用户手动旋转。
问题是,当我单击按钮时,onCreate 中的 OrientationEventListener 也被激活,因为屏幕旋转时活动会再次启动,从而重置用于维护按钮单击记录的布尔值。
我需要的是,仅当移动设备本身旋转而不是通过单击时,才发生orientationEventListener回调操作。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
val button = findViewById<ImageButton>(R.id.button)
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
//call function that rotates the screen for example:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
})
val sharedPref = getSharedPreferences("string", MODE_PRIVATE)
val orientationListener: OrientationEventListener = object : OrientationEventListener(
applicationContext
) {
override fun onOrientationChanged(orientation: Int) {
//call function that needs to work only if the user rotates the phone without clicking the button
}
}
if (orientationListener.canDetectOrientation()) {
orientationListener.enable();
}
}
我尝试使用布尔值来指示按钮是否被单击,但是每次旋转发生时,无论是手动还是通过单击,活动都会被销毁并重新启动,因此布尔值被重置并调用 onCreate/OrientationEventListener 。有什么建议吗?
P.S.:OrientationEventListener 并不是这个问题的焦点,而是当识别到移动设备旋转时我需要在其中执行的操作。因此,如果您有其他方法可以做到这一点,我也想听听。轮换后重新开始的活动也不是我需要的,但每次轮换发生时都会发生这种情况,我不知道是否可以阻止它。
您可以将以下配置添加到清单文件中,以在发生配置更改(例如屏幕旋转)时停止重新创建 Activity。 将以下内容添加到清单文件中 MainActivity 的标签中:
android:configChanges="orientation|screenSize"
这将防止在方向改变时重新创建活动。
下一步:在 MainActivity 中,重写 onConfigurationChanged() 方法来处理方向更改,而无需重新创建 Activity:
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
isButtonClicked = false // Reset flag after handling programmatic rotation
// Handle orientation changes here, e.g., update layout if needed
}
您可以在此处重置 isButtonClicked 布尔值,以了解屏幕方向是否因按钮单击或手动旋转而改变。
最后在 onCreate() 方法中,您可以在触发方向更改之前将 isButtonClicked 布尔值设置为 tru,并在侦听器内检查它的值,以跳过仅在手动旋转发生时才运行的代码。
val button = findViewById<ImageButton>(R.id.button)
button.setOnClickListener {
isButtonClicked = true
// Call function that rotates the screen, e.g.,
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
}
val orientationListener = object : OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
if (!isButtonClicked) {
// Call function that needs to work only for manual rotation
// ... your action here ...
}
}
}
编辑:
这是进入 MainActivity 的完整代码,用于通过单击按钮旋转屏幕并保留布尔值的状态。
由于我们已经在由于设备旋转而发生方向变化时禁用了 Activity 重新创建,因此我们必须使用orientationChangeListener 将设备旋转的方向设置为相应的状态。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var isButtonClicked = false
@SuppressLint("SwitchIntDef", "SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("TAG", "Inside onCreate!")
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val btnRotateScreen = findViewById<Button>(R.id.btn_rotate_screen)
btnRotateScreen.setOnClickListener {
isButtonClicked = true
Log.d("TAG", "current orientation: ${resources.configuration.orientation}")
when (resources.configuration.orientation) {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT,
Configuration.ORIENTATION_PORTRAIT -> {
requestedOrientation =
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
Configuration.ORIENTATION_LANDSCAPE,
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE -> {
requestedOrientation =
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
}
}
}
val orientationListener = object : OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
Log.d("TAG", "Inside onOrientationChanged: orientation int val: $orientation")
var isUpdated = false
when (orientation) {
in 0..10,
in 350..360,
in 170..190 -> {
requestedOrientation =
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
isUpdated = true
}
in 80..100,
in 260..280 -> {
requestedOrientation =
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
isUpdated = true
}
}
if (isUpdated) {
// Do Task that needs to be done when orientation changes happens due to
// device rotation not button click.
Log.d("TAG", "Orientation changed by rotation, set button clicked to false")
isButtonClicked = false
}
}
}
if (orientationListener.canDetectOrientation()) {
orientationListener.enable();
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
Log.d(
"TAG",
"inside onConfiguration changed, newConfig orientation: ${newConfig.orientation}"
)
}
}
如果您需要更多说明,请随时发表评论。