单击按钮时方向发生变化时避免 OrientationEventListener 回调

问题描述 投票:0回答:1

我的活动的 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 并不是这个问题的焦点,而是当识别到移动设备旋转时我需要在其中执行的操作。因此,如果您有其他方法可以做到这一点,我也想听听。轮换后重新开始的活动也不是我需要的,但每次轮换发生时都会发生这种情况,我不知道是否可以阻止它。

android kotlin android-studio
1个回答
0
投票

您可以将以下配置添加到清单文件中,以在发生配置更改(例如屏幕旋转)时停止重新创建 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}"
        )
    }
}

如果您需要更多说明,请随时发表评论。

© www.soinside.com 2019 - 2024. All rights reserved.