【问题标题】:How to implement the Android ActionBar back button?如何实现Android ActionBar 后退按钮?
【发布时间】:2012-04-23 22:12:35
【问题描述】:

我有一个带有列表视图的活动。当用户单击项目时,项目“查看器”打开:

List1.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

        Intent nextScreen = new Intent(context,ServicesViewActivity.class);
        String[] Service = (String[])List1.getItemAtPosition(arg2);

        //Sending data to another Activity
        nextScreen.putExtra("data", datainfo);
        startActivityForResult(nextScreen,0);
        overridePendingTransition(R.anim.right_enter, R.anim.left_exit);
    }
});

这很好用,但在操作栏上,应用图标旁边的后退箭头没有被激活。我错过了什么吗?

【问题讨论】:

  • getActionBar().setDisplayHomeAsUpEnabled(true); 在 onCreate 和 switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}onOptionsItemSelected ?都在 ServicesViewActivity
  • 为什么不作为答案搁置?

标签: java android android-3.0-honeycomb


【解决方案1】:

Selvin 已经发布了正确答案。在这里,漂亮的代码解决方案:

public class ServicesViewActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // etc...
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

函数NavUtils.navigateUpFromSameTask(this)需要你在AndroidManifest.xml文件中定义父activity

<activity android:name="com.example.ServicesViewActivity" >
    <meta-data
     android:name="android.support.PARENT_ACTIVITY"
     android:value="com.example.ParentActivity" />
</activity>

请参阅here 了解更多信息。

【讨论】:

  • 在我的情况下,我正在寻找一种在返回父级时不调用 onCreate 的方法。为此,我使用了您的实现,但调用了 finish() 而不是 NavUtils.navigateUpFromSameTask(this)。 finish() 调用我的 onStart 而不是 onCreate 这对我来说更理想。
  • 在清单中设置元数据是使导航按钮正常工作的关键
  • 如果您正在使用支持库,请使用 getActionBar().setDisplayHomeAsUpEnabled(true);
  • 如何改变“擦拭”的方向?默认情况下,实现这个后退导航会从右向左扫过屏幕,看起来就像是在加载一个新屏幕。但是,我希望它从左到右擦除,就像按设备自己的后退键一样。
  • 我收到错误:原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)'
【解决方案2】:

确保在 Activity 中启用了 ActionBar 主页按钮:

Android,API 5+:

@Override
public void onBackPressed() {
     ...
     super.onBackPressed();
}

ActionBarSherlock 和 App-Compat,API 7+:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

Android,API 11+:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

扩展 ActionBarActivity 的示例 MainActivity

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home: 
            // API 5+ solution
            onBackPressed();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

这样你想要的所有活动都可以有后台。

Android,API 16+:

http://developer.android.com/training/implementing-navigation/ancestral.html

AndroidManifest.xml:

<application ... >
    ...
    <!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.myfirstapp.MainActivity" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name="com.example.myfirstapp.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <!-- The meta-data element is needed for versions lower than 4.1 -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

扩展 ActionBarActivity 的示例 MainActivity

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

【讨论】:

  • 当我更改 getSupportActionBar().setDisplayHomeAsUpEnabled(true);进入 getActionBar().setDisplayHomeAsUpEnabled(true);并在内部和外部的 onCreate 方法中添加了这些 @SuppressLint("NewApi") For REF : => developer.android.com/training/implementing-navigation/…
  • @ganpath 小心,使用 getActionBar 适用于 API 11+
【解决方案3】:

要启用 ActionBar 后退按钮,您显然需要在 Activity 中添加一个 ActionBar。 这是由您使用的主题设置的。您可以在AndroidManfiest.xml 中为您的活动设置主题。如果您使用例如 @android:style/Theme.NoTitleBar 主题,则您没有 ActionBar。在这种情况下,对 getActionBar() 的调用将返回 null。因此,请先确保您有一个 ActionBar。

下一步是将android:parentActivityName 设置为您要在按下返回按钮时导航的活动。这也应该在AndroidManifest.xml 中完成。

现在您可以在“子”活动的onCreate 方法中启用后退按钮。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

现在您应该实现后退按钮的逻辑。您只需在“子”活动中覆盖 onOptionsItemSelected 方法并检查返回按钮的 ID,即 android.R.id.home

现在,如果您没有在 AndroidManifest.xml 中指定 android:parentActivityName,您可以触发方法 NavUtils.navigateUpFromSameTask(this); 但是,这将使您的应用程序崩溃。

有时这正是您想要的,因为它提醒您忘记了“某事”。因此,如果您想防止这种情况发生,您可以使用getParentActivityIntent() 方法检查您的活动是否有父项。如果返回 null,则说明您没有指定父级。

在这种情况下,您可以触发onBackPressed() 方法,其作用与用户按下设备上的后退按钮基本相同。一个不会让您的应用崩溃的好的实现是:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            if (getParentActivityIntent() == null) {
                Log.i(TAG, "You have forgotten to specify the parentActivityName in the AndroidManifest!");
                onBackPressed();
            } else {
                NavUtils.navigateUpFromSameTask(this);
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

请注意NavUtils.navigateUpFromSameTask(this);onBackPressed() 之间用户看到的动画是不同的。

走哪条路取决于您,但我发现该解决方案很有帮助,尤其是当您为所有活动使用基类时。

【讨论】:

    【解决方案4】:

    AndroidManifest 文件:

        <activity android:name=".activity.DetailsActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="br.com.halyson.materialdesign.activity.HomeActivity" />
        </activity>
    

    添加DetailsActivity:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);   
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
    

    它的工作:]

    【讨论】:

    • 看来这对我来说是最简单的方法。谢谢
    【解决方案5】:

    OnCreate 方法中添加:

    if (getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
    

    然后添加这个方法:

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

    【讨论】:

      【解决方案6】:

      Android 注释:

      @OptionsItem(android.R.id.home)
      void homeSelected() {
          onBackPressed();
      }
      

      来源:https://github.com/excilys/androidannotations

      【讨论】:

        【解决方案7】:

        我认为onSupportNavigateUp() 是最简单也是最好的方法

        在下面的 stackoverflow 答案中查看完整的解决方案。链接:Click here for complete code

        【讨论】:

        • 太棒了!为我工作。谢谢!
        【解决方案8】:

        https://stackoverflow.com/a/46903870/4489222

        要做到这一点,只需两个步骤,

        第1步:转到AndroidManifest.xml并在标签中添加参数 - android:parentActivityName=".home.HomeActivity"

        示例:

         <activity
            android:name=".home.ActivityDetail"
            android:parentActivityName=".home.HomeActivity"
            android:screenOrientation="portrait" />
        

        第 2 步:在 ActivityDetail 中为上一页/活动添加您的操作

        示例:

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
           switch (item.getItemId()) {
              case android.R.id.home: 
                  onBackPressed();
                  return true;
           }
           return super.onOptionsItemSelected(item);}
        }
        

        【讨论】:

          【解决方案9】:

          以下步骤足以返回按钮:

          第 1 步: 这段代码应该在 Manifest.xml 中

          <activity android:name=".activity.ChildActivity"
                  android:parentActivityName=".activity.ParentActivity"
                  android:screenOrientation="portrait">
                  <meta-data
                      android:name="android.support.PARENT_ACTIVITY"
                      android:value=".activity.ParentActivity" /></activity>
          

          第 2 步: 你不会给的

          finish();
          

          在启动子活动时在您的父活动中。

          第 3 步: 如果你需要从 Child Activity 回到 Parent Activity,那么你只需为 Child Activity 提供这段代码。

          startActivity(new Intent(ParentActivity.this, ChildActivity.class));
          

          【讨论】:

            【解决方案10】:
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            

            onCreated 方法中用于新的 api。

            【讨论】:

              【解决方案11】:

              如果您使用的是工具栏,我也遇到了同样的问题。我按照这两个步骤解决了

              1. 在 AndroidManifest.xml 中
              <activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
              
              1. 在 SecondActivity 中,添加这些...
              Toolbar toolbar = findViewById(R.id.second_toolbar);
              setSupportActionBar(toolbar);
              getSupportActionBar().setDisplayShowTitleEnabled(false);
              getSupportActionBar().setDisplayHomeAsUpEnabled(true);
              

              【讨论】:

                【解决方案12】:

                基于 Jared 的回答,我必须在多个活动中启用并实现操作栏后退按钮行为,并创建此帮助程序类以减少代码重复。

                public final class ActionBarHelper {
                    public static void enableBackButton(AppCompatActivity context) {
                        if(context == null) return;
                
                        ActionBar actionBar = context.getSupportActionBar();
                        if (actionBar == null) return;
                
                        actionBar.setDisplayHomeAsUpEnabled(true);
                    }
                }
                

                在活动中的用法:

                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    ...
                
                    ActionBarHelper.enableBackButton(this);
                }
                

                【讨论】:

                  【解决方案13】:

                  我自己也在尝试,还有一件事对我有用:

                  
                          when(item.itemId) {
                              R.id.action_signup -> signup() //other menu item
                              android.R.id.home -> viewRoot.findNavController().navigateUp() //back 
                          }
                  
                          return super.onOptionsItemSelected(item)
                      }
                  

                  我正在使用 Jetpack 导航,因此这是获取 NavController 的调用。

                  【讨论】:

                    【解决方案14】:

                    另一种选择是将辅助活动的 parentActivityName 设置为应用程序清单文件中的 MainActifity

                    <activity
                            android:name=".ServiceViewActivity"
                            android:parentActivityName=".MainActivity"/>
                    

                    【讨论】:

                      猜你喜欢
                      • 2019-12-10
                      • 1970-01-01
                      • 2016-04-10
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-06-06
                      • 2016-08-03
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多