Androidx OnBackPressedDispatcher – как использовать нажатие кнопки «Назад»

Я хотел бы, чтобы onBackPressedDispatcher иногда поглощал нажатие кнопки «Назад», но я не вижу для этого возможности. что происходит, так это то, что мы только сегодня пытаемся перейти на onBackPressedDispatcher в androidX, но мы уже переопределили onBackPress в действии. поэтому, когда наш onBackPressedDispatcher впоследствии вызывает OnBackPressedCallback, также происходит вызов переопределения действий onBackPressed. мы не хотим этого. onBackpressed следует потреблять на месте. вот что у меня есть до сих пор:

    const val TAG = "MyTag"

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)
        MyTester(this)
    }

    override fun onBackPressed() {
        super.onBackPressed()
        Log.v(TAG, "Activities class back button Pressed")

    }

    inner class MyTester(var activity: AppCompatActivity) {
        init {
            addBackCB()
        }

        fun addBackCB() {
            var callback = object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                    Log.v(TAG, "inner class MyTester back button")
                }
            }
            activity.onBackPressedDispatcher.addCallback(activity, callback);
        }
    }
}

который печатает следующее:

V/MyTag: inner class MyTester back button
V/MyTag: Activities class back button Pressed

если я не вызываю super.onBackPressed(), то диспетчер даже не работает. ему нужен этот звонок.


person j2emanue    schedule 07.09.2019    source источник


Ответы (1)


Это потому, что OnBackPressedDispatcher вызывается в ComponentActivity.onBackPressed(), если вы посмотрите на исходный код:

    @Override
    @MainThread
    public void onBackPressed() {
        mOnBackPressedDispatcher.onBackPressed();
    }

Таким образом, вы никогда не достигнете своего обратного вызова, если переопределите onBackPressed и никогда не вызовете метод super. Я думаю, что вся идея OnBackPressedDispatcher заключается в том, что вам не нужно переопределять Activity.onBackPressed, если вы хотите, чтобы ваши фрагменты перехватывали обратное нажатие. Об этом упоминается в одном из руководств.

Если вы действительно хотите, чтобы ваша активность обрабатывала обратное нажатие, вы можете попробовать что-то вроде этого в своем переопределении:

    if (onBackPressedDispatcher.hasEnabledCallbacks()) {
      // There's an active callback; let the fragment handle it
      super.onBackPressed()
    } else {
      // Do your activity's back press handling here
    }

Однако будьте осторожны, делая это. Попробовав это самостоятельно, вы можете обнаружить, что hasEnabledCallbacks вернет true, даже если вы сами не добавили никаких обратных вызовов. Это связано с тем, что ваш FragmentManager имеет собственный обратный вызов, который будет включен всякий раз, когда backStackEntryCount > 0. Я не уверен, есть ли для этого быстрый обходной путь.

person Alex H    schedule 11.09.2019
comment
привет, да, это работает, но у меня есть небольшой вопрос, когда я возвращаюсь к вложенному фрагменту, он работает нормально, теперь я нахожусь в первой активности, теперь нажмите кнопку, чтобы открыть пустой экран - person Sunil Chaudhary; 29.07.2020
comment
это спасло мой день!! Благодарность - person neo; 07.07.2021