覆盖后退按钮以充当主页按钮

Posted

技术标签:

【中文标题】覆盖后退按钮以充当主页按钮【英文标题】:Override back button to act like home button 【发布时间】:2011-01-01 06:55:28 【问题描述】:

按下后退按钮时,我希望我的应用程序进入停止状态,而不是销毁状态。

android docs 中声明:

...并非所有活动都具有在按下 BACK 时被销毁的行为。当用户在 Music 应用程序中开始播放音乐然后按下 BACK 时,应用程序会覆盖正常的返回行为,防止播放器 Activity 被破坏,并继续播放音乐,即使它的 Activity 不再可见

如何在我自己的应用程序中复制此功能?

我觉得应该有三种可能……

    捕获后退按钮按下(如下所示),然后调用主页按钮调用的任何方法。

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
        if ((keyCode == KeyEvent.KEYCODE_BACK)) 
            Log.d(this.getClass().getName(), "back button pressed");
        
        return super.onKeyDown(keyCode, event);
    
    

    捕获后退按钮按下,然后欺骗主页按钮按下。

    捕获后退按钮按下,然后启动主屏幕的 Activity,有效地将我的应用程序的 Activity 置于停止状态。

编辑: 我了解服务,并且正在与此问题相关的应用程序中使用服务。这个问题具体是关于在按下后退按钮时将 Activity 置于停止状态而不是销毁状态。

【问题讨论】:

看到类似的答案***.com/questions/5914040/… 【参考方案1】:

大多数时候您需要创建一个Service 来在后台执行某些操作,而您的可见Activity 只需控制这个Service。 (我确信音乐播放器的工作方式相同,因此文档中的示例似乎有点误导。)如果是这种情况,那么您的 Activity 可以像往常一样 finish 并且 Service 仍然是正在运行。

更简单的方法是捕获Back 按钮按下并调用moveTaskToBack(true),如下所示:

// 2.0 and above
@Override
public void onBackPressed() 
    moveTaskToBack(true);


// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
    if (keyCode == KeyEvent.KEYCODE_BACK) 
        moveTaskToBack(true);
        return true;
    
    return super.onKeyDown(keyCode, event);

我认为首选选项应该是让 Activity 正常完成并能够重新创建自身,例如如果需要,从服务中读取当前状态。但moveTaskToBack 有时可以用作快速替代方案。

注意:正如 Dave 所指出的,Android 2.0 下面引入了一个新的onBackPressed 方法,these recommendations 介绍了如何处理后退按钮。

【讨论】:

moveTaskToBack() 似乎可以按需要工作。使用这种方法可能有什么缺点?是否存在可能无法按预期工作的情况? 在仔细阅读其文档后,我实际上认为它应该可以正常工作。 (我最初以为它适用于活动,但实际上它说的是“包含此活动的任务”。)但是您当然应该自己测试它。 :) 感谢 Mirko,该方法似乎运行良好。如果您在答案底部为稍后查看此问题的人更突出您的编辑可能会很酷 - 因为那是我一直在寻找的! 请阅读android-developers.blogspot.com/2009/12/… 了解处理返回键的推荐方式。 @bdls 理论上,如果系统资源不足,您的后台活动可能会被系统杀死,因此为了安全起见,无论如何它应该能够重新创建自己。我查看了 Android Music 应用的源代码,没有看到任何特殊的后退按钮处理。【参考方案2】:

使用以下代码:

public void onBackPressed()     
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);

【讨论】:

【参考方案3】:

如果您想使用返回按钮,请查看this post on the Android Developer Blog。它涵盖了在 Android 2.0 中执行此操作的更简单方法,以及在 1.x 和 2.0 上运行的应用程序执行此操作的最佳方法。

但是,如果您的 Activity 已停止,它仍然可能会被终止,具体取决于设备上的内存可用性。如果您希望进程在没有 UI 的情况下运行,您应该创建一个 Service。 The documentation says the following about Services:

服务没有可视化的用户界面,而是在后台无限期地运行。例如,服务可能会在用户处理其他事务时播放背景音乐,或者它可能会通过网络获取数据或计算某些内容并将结果提供给需要它的活动。

这些似乎符合您的要求。

【讨论】:

【参考方案4】:

尝试覆盖 android.app.Activity 类中定义的 void onBackPressed()

【讨论】:

因为 android 2.0 这是正确的覆盖。 developer.android.com/sdk/android-2.0.html【参考方案5】:

如果它对其他人有帮助,我有一个带有 2 个布局的活动,我打开和关闭了可见性,试图模拟一种 page1 > page2 结构。如果他们在第 2 页并按下后退按钮,我希望他们返回到第 1 页,如果他们在第 1 页上按下后退按钮,它应该仍然可以正常工作。它非常基本,但它有效

@Override
public void onBackPressed() 
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE)
        togglePageLayout(); // my method to toggle the views
        return;
    else
        super.onBackPressed(); // allows standard use of backbutton for page 1
    


希望它可以帮助某人, 干杯

【讨论】:

【参考方案6】:

工作示例..

确保不要调用 super.onBackPressed();

@Override
public void onBackPressed() 
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);

这样,您的 Back Button 就像 Home button 一样。它不会完成您的活动,而是将其带到后台

第二种方法是在onBackPressed中调用moveTaskToBack(true);并确保删除super.onBackPressed

【讨论】:

【参考方案7】:

更好的是OnPause():

当活动进入后台但尚未(尚未)被杀死时,作为活动生命周期的一部分调用。 onResume() 的对应项。

当activity B在activity A前面启动时,这个回调会在A上被调用。B不会被创建,直到A的onPause()返回,所以一定要enter code here在这里不要做任何冗长的事情。

此回调主要用于保存活动正在编辑的任何持久状态,并确保如果没有足够的资源来启动新活动而不首先杀死该活动,则不会丢失任何内容。

这也是执行诸如停止动画和其他消耗大量 CPU 的事情的好地方,以便尽快切换到下一个活动,或关闭独占访问的资源,例如相机。

【讨论】:

【参考方案8】:

在 android 2.0 之后重写 onBackPressed()。 比如

@Override
public void onBackPressed() 
    moveTaskToBack(true);

【讨论】:

【参考方案9】:

我已经使用 @Mirko N. answser 使用了新的自定义编辑文本

 public class EditViewCustom extends EditText 

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
    

    public EditViewCustom(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    public EditViewCustom(Context context) 
        super(context);
    

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout)
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) 
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) 
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          

        return super.onKeyPreIme(keyCode, event);
    


然后从您的活动中设置数据

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

谢谢。

【讨论】:

【参考方案10】:

我已经尝试了上述所有解决方案,但没有一个对我有用。当我尝试以调用 onCreate 的方式返回 MainActivity 时,以下代码帮助了我:

Intent.FLAG_ACTIVITY_CLEAR_TOP 是关键。

  @Override
  public void onBackPressed() 
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  

【讨论】:

以上是关于覆盖后退按钮以充当主页按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中停用或覆盖appBar中的箭头后退按钮?

如何覆盖 Apple Watch 后退按钮以弹出到根控制器

如何覆盖 Flutter 中的“返回”按钮? [复制]

如何完全覆盖导航栏的后退按钮操作?

Flutter 中的设备后退按钮覆盖

Cordova 后退按钮覆盖默认行为