onbackpressed()已弃用。什么是选择?

发布于 2025-02-07 20:29:46 字数 1448 浏览 3 评论 0 原文

我已经升级了 targetsdkversion compilesdkversion 33

我现在得到一个警告,告诉我 onbackpressed 已弃用。

我看到建议使用 android.window.onbackinvokedcallback ://developer.android.com/reference/androidx/activity/onbackpressedcallback“ rel =“ noreferrer”> androidx.activity.onbackpressevervity.onbackpressedcallback 代替处理返回导航。谁能帮助我使用更新的方法?

示例

用例

i使用 if(istaskroot){} onbackpressed()检查活动是否是活动堆栈上的最后一个方法。

override fun onBackPressed() {
    if (isTaskRoot) { // Check whether this activity is last on the activity stack. (Check whether this activity opened from a Push Notification.)
        startActivity(Intent(mContext, Dashboard::class.java))
        finish()
    } else {
        finishWithResultOK()
    }
}

I have upgraded targetSdkVersion and compileSdkVersion to 33.

I am now getting a warning telling me that onBackPressed is deprecated.

I see suggestions to use android.window.OnBackInvokedCallback or androidx.activity.OnBackPressedCallback to handle back navigation instead. Can anyone can help me use the updated method?

Example

onBackPressedDeprecated

Use Case

I use if (isTaskRoot) {} inside the onBackPressed() method to check whether the activity is the last one on the activity stack.

override fun onBackPressed() {
    if (isTaskRoot) { // Check whether this activity is last on the activity stack. (Check whether this activity opened from a Push Notification.)
        startActivity(Intent(mContext, Dashboard::class.java))
        finish()
    } else {
        finishWithResultOK()
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(26

谁把谁当真 2025-02-14 20:29:47

如果您使用的是Java,那么这是我正在这样做的方法。

// Creating a global variable
private final OnBackPressedDispatcher onBackPressedDispatcher = getOnBackPressedDispatcher();
// In your onCreate method
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.my_activity);

   // Add callback listener
   onBackPressedDispatcher.addCallback(new OnBackPressedCallback(true) {
       @Override
       public void handleOnBackPressed() {
           // Handle onback pressed
       }
   });
}

然后,如果您想强制呼叫onbacked,则可以使用以下方式进行以下操作:

mBtnBack.setOnClickListener(v -> onBackPressedDispatcher.onBackPressed());

If you're using Java then here's a way I'm doing it.

// Creating a global variable
private final OnBackPressedDispatcher onBackPressedDispatcher = getOnBackPressedDispatcher();
// In your onCreate method
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.my_activity);

   // Add callback listener
   onBackPressedDispatcher.addCallback(new OnBackPressedCallback(true) {
       @Override
       public void handleOnBackPressed() {
           // Handle onback pressed
       }
   });
}

Then if you want to force call onBackPressed you can do it using:

mBtnBack.setOnClickListener(v -> onBackPressedDispatcher.onBackPressed());
屋檐 2025-02-14 20:29:47

如果您喜欢“后面”按钮处理,则需要在活动的OnCreate()方法中进行此部分。不要忘记实际完成handleonbackpressed()中的活动。

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        //Add custom actions here (like before in onBackPressed())
        finish();
    }
});

如果您的活动中有箭头,则涉及用于AppCompatactivity的方法OnSupportNavigateUp()。

因此,您还需要处理此问题。这样做。

@Override
public boolean onSupportNavigateUp() {
    getOnBackPressedDispatcher().onBackPressed();
    return true;
}

If you like the back button handled you need this part in your onCreate() method of your activity. Don't forget to actually finish the activity in the handleOnBackPressed().

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        //Add custom actions here (like before in onBackPressed())
        finish();
    }
});

If you have a up arrow inside your activity, this involves the method onSupportNavigateUp() for AppCompatActivity.

So you also need to handle this. Do it this way.

@Override
public boolean onSupportNavigateUp() {
    getOnBackPressedDispatcher().onBackPressed();
    return true;
}
风追烟花雨 2025-02-14 20:29:47

奖励:当onbackpressed使用如下(根据此i/o谈话),

val callback = onBackPressedDispatcher.addCallback(this, false) {
    binding.drawerLayout.closeDrawer(GravityCompat.START)
}
            
binding.drawerLayout.addDrawerListener(object : DrawerListener {  
        
    override fun onDrawerOpened(drawerView: View) {
        callback.isEnabled = true
    }
        
    override fun onDrawerClosed(drawerView: View) {
        callback.isEnabled = false
    }

    override fun onDrawerSlide(drawerView: View, slideOffset: Float) = Unit    
    override fun onDrawerStateChanged(newState: Int) = Unit
})

Bonus: To close DrawerLayout when onBackPressed use like below (according to this I/O talk),

val callback = onBackPressedDispatcher.addCallback(this, false) {
    binding.drawerLayout.closeDrawer(GravityCompat.START)
}
            
binding.drawerLayout.addDrawerListener(object : DrawerListener {  
        
    override fun onDrawerOpened(drawerView: View) {
        callback.isEnabled = true
    }
        
    override fun onDrawerClosed(drawerView: View) {
        callback.isEnabled = false
    }

    override fun onDrawerSlide(drawerView: View, slideOffset: Float) = Unit    
    override fun onDrawerStateChanged(newState: Int) = Unit
})
北恋 2025-02-14 20:29:47

这是在活动中实现OnbackPressedCallback的扩展功能。

fun AppCompatActivity.addOnBackPressedDispatcher(onBackPressed: () -> Unit = { finish() }) {
    onBackPressedDispatcher.addCallback(
        this,
        object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                onBackPressed.invoke()
            }
        }
    )
}

用法:

addOnBackPressedDispatcher {
    //doSomething()
}

Here is the extension function to implement OnBackPressedCallback in activity.

fun AppCompatActivity.addOnBackPressedDispatcher(onBackPressed: () -> Unit = { finish() }) {
    onBackPressedDispatcher.addCallback(
        this,
        object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                onBackPressed.invoke()
            }
        }
    )
}

Usage:

addOnBackPressedDispatcher {
    //doSomething()
}
笨死的猪 2025-02-14 20:29:47

我通过简单地将扩展名添加到 appCompatactivity :我

fun AppCompatActivity.onBackButtonPressed(callback: (() -> Unit)? = null){
    val onBackPressed: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            callback?.let { callback() } ?: run { finish() }
        }
    }
    this.onBackPressedDispatcher.addCallback(this, onBackPressed)
}

可以通过两种方式调用“ onbackbuttonpressed”来使用它来解决此问题,以两种方式

1-实现后面按下以完成活动

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // implement back pressed
    onBackButtonPressed()
}

2-句柄后面的partive 2-句柄后面按下:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // implement back pressed
    onBackButtonPressed {
        // handle back pressed click here,

    }
}

I solved this by simply adding an extension to AppCompatActivity:

fun AppCompatActivity.onBackButtonPressed(callback: (() -> Unit)? = null){
    val onBackPressed: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            callback?.let { callback() } ?: run { finish() }
        }
    }
    this.onBackPressedDispatcher.addCallback(this, onBackPressed)
}

So I can use it by calling "onBackButtonPressed" in two ways

1- Implement back pressed to finish activity

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // implement back pressed
    onBackButtonPressed()
}

2- Handle back pressed clicks:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // implement back pressed
    onBackButtonPressed {
        // handle back pressed click here,

    }
}
呆橘 2025-02-14 20:29:47

首先,我们必须添加一个回调对象,因为, onbackpresseddispatcher.onbackpresse()触发了呼叫当前添加的回调,以相反的顺序添加。
因此,添加回调后,我们应该调用方法 onbackpressed()

代码(在Kotlin中)如下:

 onBackPressedDispatcher.addCallback(this,object :OnBackPressedCallback(true){
            override fun handleOnBackPressed() {
                Log.i("TAG","back has been called")
                finish()
            }
        })

onBackPressedDispatcher.onBackPressed()

first,we have to add a callback object because, onBackPressedDispatcher.onBackPressed() triggers a call to the currently added callbacks in reverse order in which they were added.
So after adding the callback only we should call the method onBackPressed()

The code (in kotlin) is as follows:

 onBackPressedDispatcher.addCallback(this,object :OnBackPressedCallback(true){
            override fun handleOnBackPressed() {
                Log.i("TAG","back has been called")
                finish()
            }
        })

onBackPressedDispatcher.onBackPressed()
我一直都在从未离去 2025-02-14 20:29:47

基于上面的所有答案( this this )我创建了这些简单的扩展名,这些扩展使您可以使用Onbackpressed函数的相同体验。我们使用 onbackpresseddispatcher 来处理返回按钮。

首先,将 appCompat:1.6.1 (或本库的任何较新版本)添加到您的gradle配置中。

implementation 'androidx.appcompat:appcompat:1.6.1'

然后,基于目标视图,您可以使用以下扩展名之一:

活动:

fun Activity.onBackButtonPressed(callback: (() -> Boolean)) {
    (this as? FragmentActivity)?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            if (!callback()) {
                remove()
                performBackPress()
            }
        }
    })
}

fun Activity.performBackPress() {
    (this as? FragmentActivity)?.onBackPressedDispatcher?.onBackPressed()
}

片段:

fun Fragment.onBackButtonPressed(callback: (() -> Boolean)) {
    requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            if (!callback()) {
                remove()
                performBackPress()
            }
        }
    })
}

fun Fragment.performBackPress() {
    requireActivity().onBackPressedDispatcher.onBackPressed()
}

对话:

fun Dialog.onBackButtonPressed(callback: (() -> Boolean)) {
    setOnKeyListener { _, keyCode, event ->
        if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
            callback()
        } else {
            false
        }
    }
}

用法:

将此功能添加到您的 increate()方法:

onBackButtonPressed {
    // Do your job
    // Return "false" if you want to system perform back
    // Return "true" if you want to override the back functionality
    true
}

如果您想完全覆盖返回按钮,则可以返回 true ,并且如果让系统处理返回按钮,则需要在回调结束时返回 false

最后但并非最不重要的一点是,如果您想手动执行活动 fragment 中的后退按钮,只需致电:

performBackPress() // replacement for deprecated onBackPressed()

Based on all answers above (this, and this) I created these simple extensions which give you the same experience of using the onBackPressed function. we use onBackPressedDispatcher for handling the back button.

First, add appcompat:1.6.1 (or any newer version of this library) to your gradle config.

implementation 'androidx.appcompat:appcompat:1.6.1'

Then based on your target view you can use one of these extensions:

Activity:

fun Activity.onBackButtonPressed(callback: (() -> Boolean)) {
    (this as? FragmentActivity)?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            if (!callback()) {
                remove()
                performBackPress()
            }
        }
    })
}

fun Activity.performBackPress() {
    (this as? FragmentActivity)?.onBackPressedDispatcher?.onBackPressed()
}

Fragment:

fun Fragment.onBackButtonPressed(callback: (() -> Boolean)) {
    requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            if (!callback()) {
                remove()
                performBackPress()
            }
        }
    })
}

fun Fragment.performBackPress() {
    requireActivity().onBackPressedDispatcher.onBackPressed()
}

Dialog:

fun Dialog.onBackButtonPressed(callback: (() -> Boolean)) {
    setOnKeyListener { _, keyCode, event ->
        if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
            callback()
        } else {
            false
        }
    }
}

Usage:

Add this function to your OnCreate() method:

onBackButtonPressed {
    // Do your job
    // Return "false" if you want to system perform back
    // Return "true" if you want to override the back functionality
    true
}

If you want to fully override the back button you can return true and in case of letting the system handle the back button, you need to return false at the end of the callback.

Last but not least, if you want to manually perform the back button in your Activity or Fragment, just simply call:

performBackPress() // replacement for deprecated onBackPressed()
把梦留给海 2025-02-14 20:29:47

设置覆盖默认行为的能力:
(调用 setUpbackpressedhandling()来自活动 increate()):

  private fun setupBackPressedHandling() {
        onBackPressedDispatcher.addCallback(this) {
            if (!backPressHandled())
                invokeDefaultBackPressedHandling()
        }
    }

open fun backPressHandled(): Boolean = false

全局扩展功能:

  fun AppCompatActivity.invokeDefaultBackPressedHandling(navController: NavController?) {
    when(navController) {
        null -> {
            if (!supportFragmentManager.isStateSaved && !supportFragmentManager.popBackStackImmediate())
                finish()
        }
        else -> {
            if (!navController.popBackStack())
                finish()
        }
    }
}

To set up ability to override default behaviour:
(call setupBackPressedHandling() From Activity onCreate()):

  private fun setupBackPressedHandling() {
        onBackPressedDispatcher.addCallback(this) {
            if (!backPressHandled())
                invokeDefaultBackPressedHandling()
        }
    }

open fun backPressHandled(): Boolean = false

Global extension function:

  fun AppCompatActivity.invokeDefaultBackPressedHandling(navController: NavController?) {
    when(navController) {
        null -> {
            if (!supportFragmentManager.isStateSaved && !supportFragmentManager.popBackStackImmediate())
                finish()
        }
        else -> {
            if (!navController.popBackStack())
                finish()
        }
    }
}
娇纵 2025-02-14 20:29:47

活动:java

  1. 删除onbackpressed()

  2. 添加依赖项

    实现'androidx.AppCompat:AppCompat:1.6.1'

  3. 在您的OnCreate方法中

  • onbackinvokeddispatcher.registeronbackinvokedcallback for API级别33+

  • backword兼容性的API
    级别13+“

     导入androidx.activity.onbackpressedcallback;
         @Override
         受保护的void ongreate(捆绑savedinstancestate){
    
         super.oncreate(savedinstancestate);
    
    
         if(build.version.sdk_int> = build.version_codes.tiramisu){
             getOnbackInvokedDisPatcher()。registeronbackinvokedCallback(onbackInvokedDispatcher.priority_default,new onbackinvokedCallback(){
                         @Override
                         public void onbackinvoked(){
                             结束();
                         }
                     }
             );
         } 别的 {
             getonbackpresseddispatcher()。
                 @Override
                 public void handleonbackpressed(){
                     结束();
                 }
             });
         }
     }
     

Activity : Java

  1. Remove onBackPressed()

  2. Add dependencies

    implementation 'androidx.appcompat:appcompat:1.6.1'

  3. In your onCreate method

  • onBackInvokedDispatcher.registerOnBackInvokedCallback for API level 33+

  • onBackPressedDispatcher callback for backword compatibility "API
    level 13+"

         import androidx.activity.OnBackPressedCallback;
         @Override
         protected void onCreate(Bundle savedInstanceState) {
    
         super.onCreate(savedInstanceState);
    
    
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, new OnBackInvokedCallback() {
                         @Override
                         public void onBackInvoked() {
                             finish();
                         }
                     }
             );
         } else {
             getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
                 @Override
                 public void handleOnBackPressed() {
                     finish();
                 }
             });
         }
     }
    
暗地喜欢 2025-02-14 20:29:47

覆盖底部表的ondismiss()函数。

override fun onDismiss(dialog: DialogInterface) {
   super.onDismiss(dialog)
   //TODO your logic.
   }

override the onDismiss() function for BottomSheets.

override fun onDismiss(dialog: DialogInterface) {
   super.onDismiss(dialog)
   //TODO your logic.
   }
错々过的事 2025-02-14 20:29:47

如果您要覆盖onbackpressed(),但是如果要调用此方法,
使用此代码,您会发现:
onbackpresseddispatcher.onbackpressed()

if you're overriding the onBackPressed() its okay but if you want to call this method,
use this code and you'll find:
onBackPressedDispatcher.onBackPressed()

亣腦蒛氧 2025-02-14 20:29:47

这是一个最新的答案。您可以在此处找到文档( https://codelabs.developers.google.google.google.google 。下面将代码添加到主活动内部的OnCreate()中。除非您的项目需要其他用法,否则请参考文档。

    val onBackPressedCallback = object: OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            when {
                //when back button pressed do you own code. 
                }
            }
        }
    }
    this.onBackPressedDispatcher
        .addCallback(onBackPressedCallback) (this -> inside activity , otherwise use requireActivity())

Here is a more recent answer. You can find the documentation here(https://codelabs.developers.google.com/handling-gesture-back-navigation#4). Below add the code to your onCreate() inside main Activity. Unless your project requires other usage, reference the documentation.

    val onBackPressedCallback = object: OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            when {
                //when back button pressed do you own code. 
                }
            }
        }
    }
    this.onBackPressedDispatcher
        .addCallback(onBackPressedCallback) (this -> inside activity , otherwise use requireActivity())
疧_╮線 2025-02-14 20:29:47

对于使用 Jetpack导航的片段,您可以创建一个扩展功能,该功能将处理 Back up 按事件。

后压 - >这是按手势导航按下按钮的动作或软背按钮

up按下 - >这是将导航中的后退按钮按下访问栏左上方的动作。它的全局ID是 android.r.id.home

fragmentExtension.kt

//Global Extension Listener to call on Back or Up pressed
fun Fragment.onBackOrUpButtonPressed(navController: NavController, callback: () -> Boolean) {
    requireActivity().onBackPressedDispatcher.addCallback(
        viewLifecycleOwner,
        object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                performBackPress(navController, callback)
            }
        })

    requireActivity().addMenuProvider(object : MenuProvider {
        override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
            // No need to inflate menu items for the "Up" button, this is just to manage options
        }

        override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
            when (menuItem.itemId) {
                android.R.id.home -> {
                    performBackPress(navController, callback)
                }
            }
            return true
        }
    }, viewLifecycleOwner)

}

//Handle back press without navController
fun Fragment.performBackPress() {
    requireActivity().onBackPressedDispatcher.onBackPressed()
}

//Handle back press from fragment
fun Fragment.performBackPress(navController: NavController, callback: () -> Boolean) {
    if (!callback()) {
        if (navController.currentBackStackEntry != null && navController.popBackStack()) {
            // If NavController can handle the back press, let it do so
        } else {
            performBackPress()
        }
    }

}


//Handle back press with navController
fun Fragment.performBackPress(navController: NavController) {
    if (navController.currentBackStackEntry != null && navController.popBackStack()) {
        // If NavController can handle the back press, let it do so
    } else {
        performBackPress()
    }
}

homefragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    onBackOrUpButtonPressed(findNavController()) {
        // Do your task here

        // Return "false" if you want to system perform back
        // Return "true" if you want to override the back functionality
        true
    }


    //To manually perform the back action

    //Perform back press without navController
    performBackPress()
            //-OR-
    //Perform back press with navController
    performBackPress(findNavController())
    }

这将使处理后/向上按下没有任何麻烦的清洁片段。

For fragments using Jetpack navigation you can create an extension function, which will handle both the back and up press events.

Back press -> It is the action of pressing button by gesture navigation or soft back button

Up press -> It is the action of pressing the back button in navigation to top left of the access bar. Its global id is android.R.id.home

FragmentExtension.kt

//Global Extension Listener to call on Back or Up pressed
fun Fragment.onBackOrUpButtonPressed(navController: NavController, callback: () -> Boolean) {
    requireActivity().onBackPressedDispatcher.addCallback(
        viewLifecycleOwner,
        object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                performBackPress(navController, callback)
            }
        })

    requireActivity().addMenuProvider(object : MenuProvider {
        override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
            // No need to inflate menu items for the "Up" button, this is just to manage options
        }

        override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
            when (menuItem.itemId) {
                android.R.id.home -> {
                    performBackPress(navController, callback)
                }
            }
            return true
        }
    }, viewLifecycleOwner)

}

//Handle back press without navController
fun Fragment.performBackPress() {
    requireActivity().onBackPressedDispatcher.onBackPressed()
}

//Handle back press from fragment
fun Fragment.performBackPress(navController: NavController, callback: () -> Boolean) {
    if (!callback()) {
        if (navController.currentBackStackEntry != null && navController.popBackStack()) {
            // If NavController can handle the back press, let it do so
        } else {
            performBackPress()
        }
    }

}


//Handle back press with navController
fun Fragment.performBackPress(navController: NavController) {
    if (navController.currentBackStackEntry != null && navController.popBackStack()) {
        // If NavController can handle the back press, let it do so
    } else {
        performBackPress()
    }
}

HomeFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    onBackOrUpButtonPressed(findNavController()) {
        // Do your task here

        // Return "false" if you want to system perform back
        // Return "true" if you want to override the back functionality
        true
    }


    //To manually perform the back action

    //Perform back press without navController
    performBackPress()
            //-OR-
    //Perform back press with navController
    performBackPress(findNavController())
    }

This will give the ability to handle the back/up press with cleaner fragments without any hassle.

糖果控 2025-02-14 20:29:47

使用下面的使用,

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.iv_back -> onBackPressedMethod()
    }
}

现在创建该方法来处理返回事件

private fun onBackPressedMethod(){
    if (Build.VERSION.SDK_INT >= 33) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
               onBackPressed.invoke()
        }
    } else {
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                  onBackPressed.invoke()
                }
            })
    }
}

Use like below,

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.iv_back -> onBackPressedMethod()
    }
}

and now create that method for handling back event

private fun onBackPressedMethod(){
    if (Build.VERSION.SDK_INT >= 33) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
               onBackPressed.invoke()
        }
    } else {
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                  onBackPressed.invoke()
                }
            })
    }
}

That's it!

送你一个梦 2025-02-14 20:29:46

用以下代码替换 onbackpressed()

Kotlin
onBackPressedDispatcher.onBackPressed()
Java
getOnBackPressedDispatcher().onBackPressed();

Replace onBackPressed() with the below code.

Kotlin
onBackPressedDispatcher.onBackPressed()
Java
getOnBackPressedDispatcher().onBackPressed();
梓梦 2025-02-14 20:29:46

根据您的API级寄存器:

  • 对于API级别33+
  • 返回兼容性“ API级别13+”的回调

至少需要使用 AppCompat:1.6.0-Alpha03 ;电流是 1.6.0-Alpha04

 implementation 'androidx.appcompat:appcompat:1.6.0-alpha04'
// kotlin
import androidx.activity.addCallback

if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Back is pressed... Finishing the activity
            finish()
        }
    })
}

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
        // Back is pressed... Finishing the activity
        finish()
    }
}


更新:

感谢@ianhanniballake评论;您可以只使用 onbackpresseddispatcher 即使在API级别33+中

使用活动1.6+,

因此,您可以做:

// kotlin
import androidx.activity.addCallback

onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish()
    }
})

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
    // Back is pressed... Finishing the activity
    finish()
}

// java
import androidx.activity.OnBackPressedCallback;

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish();
    }
});

请注意,您不应覆盖 onbackpressed() onbackpresseddispatcher 不发火的回调;检查此答案 澄清了这一点。

According your API level register:

This requires to at least use appcompat:1.6.0-alpha03; the current is 1.6.0-alpha04:

 implementation 'androidx.appcompat:appcompat:1.6.0-alpha04'
// kotlin
import androidx.activity.addCallback

if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Back is pressed... Finishing the activity
            finish()
        }
    })
}

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
        // Back is pressed... Finishing the activity
        finish()
    }
}


UPDATE:

Thanks to @ianhanniballake comment; you can just use OnBackPressedDispatcher even in API level 33+

The OnBackPressedDispatcher is already going to be using the Android T specific API internally when using Activity 1.6+,

So, you can just do:

// kotlin
import androidx.activity.addCallback

onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish()
    }
})

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
    // Back is pressed... Finishing the activity
    finish()
}

// java
import androidx.activity.OnBackPressedCallback;

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish();
    }
});

Note that you shouldn't override the onBackPressed() as that will make the onBackPressedDispatcher callback not to fire; check this answer for clarifying that.

命硬 2025-02-14 20:29:46

只需替换

override fun onBackPressed() {
    super.onBackPressed() // Replace this deprecated line
}

override fun onBackPressed() {
    onBackPressedDispatcher.onBackPressed() // with this line
}

更新

覆盖fun onbackpressed()被弃用的

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        println("Back button pressed")
        // Code that you need to execute on back press, e.g. finish()
  }
})

,用以下代码替换为:将上述代码添加到活动生命周期函数中,例如 oncreate(savedinstancestate:)

Simply replace

override fun onBackPressed() {
    super.onBackPressed() // Replace this deprecated line
}

with

override fun onBackPressed() {
    onBackPressedDispatcher.onBackPressed() // with this line
}

Update

Given that override fun onBackPressed() is deprecated, replace it with the following code:

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        println("Back button pressed")
        // Code that you need to execute on back press, e.g. finish()
  }
})

Add the above code to an activity lifecycle function like onCreate(savedInstanceState:).

酷炫老祖宗 2025-02-14 20:29:46

结合了最高答案。这是一个解决方案:

1。当您需要按下后按钮时,请复制以下内容:

注意:它将自动破坏您的活动。

button.setOnClickListener {
    onBackPressedDispatcher.onBackPressed()
}

2。当您需要按下后面按钮时,请复制以下内容:

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Whatever you want
        // when back pressed
        println("Back button pressed")
        finish()
    }
})

With a combination of top answers. Here is a solution :

1. When you need to press the back button, copy this :

Note: it will automatically destroy your activity.

button.setOnClickListener {
    onBackPressedDispatcher.onBackPressed()
}

2. When you need to handle the back button pressed, copy this :

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Whatever you want
        // when back pressed
        println("Back button pressed")
        finish()
    }
})
爱人如己 2025-02-14 20:29:46

kotlin 中,这样可以工作

1-删除 onbackpressed()

2-下面 oncreate(savedinstancestate:bundle:bundle?)添加以下行:

 if (Build.VERSION.SDK_INT >= 33) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT
        ) {
           
            exitOnBackPressed()
        }
    } else {
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                  
                    Log.i("TAG", "handleOnBackPressed: Exit")
                    exitOnBackPressed()
                }
            })
    }

3--定义用于处理的新功能

fun exitOnBackPressed() {
}

In Kotlin, this way is working

1- Remove onBackPressed()

2- below onCreate(savedInstanceState: Bundle?) add these lines:

 if (Build.VERSION.SDK_INT >= 33) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT
        ) {
           
            exitOnBackPressed()
        }
    } else {
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                  
                    Log.i("TAG", "handleOnBackPressed: Exit")
                    exitOnBackPressed()
                }
            })
    }

3- Define a new function for handling

fun exitOnBackPressed() {
}
悍妇囚夫 2025-02-14 20:29:46
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class SampleActivity : AppCompatActivity(R.layout.activity_sample) {

    private val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            showAppClosingDialog()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
    }

    private fun showAppClosingDialog() {
        MaterialAlertDialogBuilder(this)
            .setTitle("Warning")
            .setMessage("Do you really want to close the app?")
            .setPositiveButton("Yes") { _, _ -> finish() }
            .setNegativeButton("No", null)
            .show()
    }
}
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class SampleActivity : AppCompatActivity(R.layout.activity_sample) {

    private val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            showAppClosingDialog()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
    }

    private fun showAppClosingDialog() {
        MaterialAlertDialogBuilder(this)
            .setTitle("Warning")
            .setMessage("Do you really want to close the app?")
            .setPositiveButton("Yes") { _, _ -> finish() }
            .setNegativeButton("No", null)
            .show()
    }
}
高速公鹿 2025-02-14 20:29:46

您可以使用

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
         
    }
})

inbackpresseddispatcher

You could use the onBackPressedDispatcher

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
         
    }
})

in here "this" means the lifeCycleOwner

醉城メ夜风 2025-02-14 20:29:46

对于Kotlin用户:

如果您尝试使用“新”方式调用默认的本机回到按钮函数,则可以在活动中使用代码波纹管。

[email protected]()

示例:

myCloseButton.setOnClickListener { [email protected]() }

上面的示例在按钮内设置了单击功能,以使按钮的作用像本机Android Back按钮。

但是,如果您想自定义OnbackpressedDisPatcher,则可以按照示例bellow,始终在您的活动中,因为此行为需要活动上下文才能工作。

自定义的Onbackpressed:

override fun onCreate(savedInstanceState: Bundle?) {
    
   val callback: OnBackPressedCallback = object : OnBackPressedCallBack(true) {
        override fun handleOnBackPressed() {
            //ToDo Implement your custom event here    
        }
    }

    [email protected](this@MyActivity, callback)
}

预期的结果是使任何onbackpresseddispatcher事件都做任何您想做的事情,或者根本不做任何事情。但这不建议这样做,因为您的用户可能会卡在屏幕上,而无需使用手机的后退按钮。因此,避免将handeronbackpressed卸载为空。因此,尝试这样的事情:

override fun handleOnBackPressed() {
    [email protected]()
}

For Kotlin Users:

If you are trying to call the Default Native Back Button function using the 'new' way, you can use the code bellow inside your Activity.

[email protected]()

example:

myCloseButton.setOnClickListener { [email protected]() }

The example above sets a click function inside a button, to make the button act like the Native Android Back Button.

However, if you want to customize the onBackPressedDispatcher, you can follow the example bellow, always inside your Activity, because this behaviour needs an Activity Context to work.

Example of Customized OnBackPressed:

override fun onCreate(savedInstanceState: Bundle?) {
    
   val callback: OnBackPressedCallback = object : OnBackPressedCallBack(true) {
        override fun handleOnBackPressed() {
            //ToDo Implement your custom event here    
        }
    }

    [email protected](this@MyActivity, callback)
}

The expected result is to make any onBackPressedDispatcher event to do whatever you want, or do nothing at all. But this is not recommended, since your user might get stuck in a screen, without being able to use his Phone's Back Button. Because of that, avoid leaving handleOnBackPressed override empty. So try something like this:

override fun handleOnBackPressed() {
    [email protected]()
}
稀香 2025-02-14 20:29:46

使用onbackpresseddispatcher.onbackpressed()而不是super.onbackpresse()

override fun onBackPressed() {
  onBackPressedDispatcher.onBackPressed() 
}

use onBackPressedDispatcher.onBackPressed() instead of super.onBackPressed()

override fun onBackPressed() {
  onBackPressedDispatcher.onBackPressed() 
}
叫嚣ゝ 2025-02-14 20:29:46

大多数答案是在要关闭活动时调用 finish()。在大多数情况下,这很好,但是在某些情况下这不起作用。例如,在Android 13中,当您按下堆栈中的最后一个活动并返回主屏幕时, ondestroy() in to n in tocy> indestroy()均未立即调用,并且应用程序保留在内存中。如果您再次打开应用程序,则它是从 onstart()开始的。

因此,在某些情况下,最好让系统处理应用程序的关闭,换句话说,让 super.onbackpresse()发生。

要替换此

override fun onBackPressed() {
    if(showPopUpBeforeClosing){
        showDialog()
    } else {
        super.onBackPressed()
    }
}

操作 -

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        if (showPopUpBeforeClosing) {
            showDialog()
        } else {
            //Removing this callback
            remove()
            onBackPressedDispatcher.onBackPressed()
        }
    }
})

如果您将回调添加到 onbackPressedDisPatcher ,并调用 onbackPressedDispatcher.onbackpresse(),它总是调用 thenge> handerbackpresse() 。一旦完成后,就没有诸如OnSuperBackpress()之类的方法或可以让系统知道的一些方法。如果您不添加回调,则系统会执行自己的操作,但是如果您添加了回调,则调用onbackpress将调用 handleonbackpresse()。因此,我们要做的是,一旦您完成了后盖,您 callback.remove()回调就会自行删除自身,现在进行 onbackpresspressepressedispatcher.onbackpresse(),它不会调用 handleonbackpressed()并按照系统的方式处理后盖,这等同于 super.onbackpresse()

Most answers are calling finish() when you want to close the activity. This works fine for most cases but in some situations this doesn't work. For example, in Android 13, when you press back on the last activity in the stack and return to the home screen, onDestroy() is not called immediately and app remains in memory. If you open up the app again right then, it starts from onStart().

So, in some situations its better to let the system handle the closing of the app, or in the other words, let super.onBackPressed() happen.

To replace this

override fun onBackPressed() {
    if(showPopUpBeforeClosing){
        showDialog()
    } else {
        super.onBackPressed()
    }
}

do this -

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        if (showPopUpBeforeClosing) {
            showDialog()
        } else {
            //Removing this callback
            remove()
            onBackPressedDispatcher.onBackPressed()
        }
    }
})

If you add a callback to the onBackPressedDispatcher, and call onBackPressedDispatcher.onBackPressed(), it always calls handleOnBackPressed(). There is no method like onSuperBackPressed() or something to let the system know to handle the backPress on its own once you're done. If you don't add the callback, then the system does its own thing, but if you've added it, then calling onBackPress will invoke handleOnBackPressed(). So what we do is, once you're done handling the back-press, you callback.remove() the callback removes itself and now when you do onBackPressedDispatcher.onBackPressed(), it will not invoke handleOnBackPressed() and handle the back-press as the system would do, which is equivalent to super.onBackPressed().

海之角 2025-02-14 20:29:46

您可以使用onbackinvokedCallback

“ 如文档中所述,请按以下内容在这里指南更新您的代码

You can use the OnBackInvokedCallback

OnBackInvokedCallback as described in the documentation and follow this guide here to update your code

梦过后 2025-02-14 20:29:46

您可以使用onbackpresseddispatcher。在一个示例下:

val back = this.onBackPressedDispatcher
back.addCallback(this, object : OnBackPressedCallback(true){
    override fun handleOnBackPressed() {
        //println("back pressed")
    }
})

you can use onBackPressedDispatcher. Below an example:

val back = this.onBackPressedDispatcher
back.addCallback(this, object : OnBackPressedCallback(true){
    override fun handleOnBackPressed() {
        //println("back pressed")
    }
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文