操作栏返回按钮无法正常工作

84

在这些Android文档的帮助下,我正在尝试实现一个操作栏返回按钮。我得到了一个如下图所示的操作栏返回按钮:

enter image description here

输出:

但是我的问题是,在查看画廊图像后,我按下操作栏返回按钮。

然后它不起作用。但它必须返回到上一页

以下是代码清单。

GalleryActivity.java:

    import android.app.ActionBar;
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.NavUtils;
    import android.view.MenuItem;

    import com.fth.android.R;

   public class GalleryActivity extends FragmentActivity {

    private int position;
    private static String id;
    private static String name;
    private DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
    private ViewPager mViewPager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_gallery);

            position = getIntent().getExtras().getInt("position");

            id = getIntent().getExtras().getString("id");

            name = getIntent().getExtras().getString("name");

            mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());

            // Set up action bar.
            final ActionBar actionBar = getActionBar();


            actionBar.setDisplayHomeAsUpEnabled(true);

           // getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_USE_LOGO|ActionBar.DISPLAY_HOME_AS_UP);

            // Set up the ViewPager, attaching the adapter.
            mViewPager = (ViewPager) findViewById(R.id.pager);
            mViewPager.setAdapter(mDemoCollectionPagerAdapter);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case android.R.id.home:

                    Intent upIntent = new Intent(this, HomeActivity.class);
                    upIntent.putExtra("position", position);
                    if (NavUtils.shouldUpRecreateTask(this, upIntent)) {

                        TaskStackBuilder.from(this)
                                .addNextIntent(upIntent)
                                .startActivities();
                        finish();
                    } else {

                        NavUtils.navigateUpTo(this, upIntent);
                    }
                    return true;
            }
            return super.onOptionsItemSelected(item);
        }


      }

GalleryDetailFragment.java:

import com.sit.fth.model.GalleryDetail;
import com.sit.fth.util.APIServiceHandler;
import com.sit.fth.util.AppConstants;
import com.sit.fth.util.AppPromoPager;

public class GalleryDetailFragment extends BaseFragment implements
        PromoPagerListener {


    private TextView countView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        this.setHasOptionsMenu(true);
        id = getArguments().getString("id");
        name = getArguments().getString("name");
        View view = inflater.inflate(R.layout.app_pager, null);



        return view;
    }

}

如果您知道如何解决这些问题,任何人都可以帮助我。谢谢。


1
你尝试在AndroidManifest中声明ParentActivities了吗? - x90
@x90,请检查我的编辑后的帖子。 - Stephen
你确定要将android:parentActivityName="com.sit.fth.activity.HomeActivity"定义为com.sit.fth.activity.HomeActivity吗?例如,你应该将HomeActivity定义为GalleryActivity的父活动,而不是自己。 - x90
@x90 HomeActivity 是一个主Activity(父Activity) - Stephen
14个回答

189

我通过在GalleryActivity中添加以下代码来解决这些问题。

ActionBar actionBar;
actionBar=getActionBar();

actionBar.setDisplayHomeAsUpEnabled(true);

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

    return super.onOptionsItemSelected(item);
}

MainActivity中:

之前是这样的:

public class HomeActivity extends BaseActivity

然后我改成了:

public class HomeActivity extends FragmentActivity

GalleryFragment中:

我使用Intent将其传递给GalleryActivity

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        Gallery gallery = (Gallery) arg0.getAdapter().getItem(arg2);

        Intent intent = new Intent(getActivity(), GalleryActivity.class);
        intent.putExtra("position", position);
        intent.putExtra("id", gallery.getGalId());
        intent.putExtra("name", gallery.getAlbumTitle());
        startActivity(intent);

        // mCallback.OnGalItemSelected(gallery.getGalId(),gallery.getAlbumTitle());
    } 

1
非常准确!onBackPressed 就是我要找的东西。我的一个设置屏幕在多个屏幕中打开,我想回到打开它的同一个活动。在 Android 活动的上下文中,“android.R.id.home” 是什么特殊 id? - RBT
@RBT 导航到父 Activity(https://developer.android.com/training/implementing-navigation/ancestral#java)。请阅读该文档。 - Stephen
在OptionsMenu的主页操作中使用“onBackPressed”不被推荐: 上面左侧角落的返回箭头用于根据屏幕之间的分层关系在应用程序内导航,系统返回按钮用于按照逆时间顺序浏览用户最近使用过的屏幕历史记录。 你可以在这里阅读更多内容:http://developer.android.com/design/patterns/navigation.html - Michele

49

请阅读这篇文章

你应该有类似于以下的内容:

    <activity
        android:name="com.sit.fth.activity.HomeActivity"
        android:screenOrientation="portrait">

    </activity>
    <activity
        android:name="com.sit.fth.activity.GalleryActivity"
        android:screenOrientation="portrait"
        android:parentActivityName="com.sit.fth.activity.HomeActivity">

    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.sit.fth.activity.HomeActivity"/>

   </activity>


在这种情况下,调用NavUtils.navigateUpFromSameTask(this)将导致导航到父活动(HomeActivity)。


@Stephen 空闲在哪里?我仍然不明白你想从哪个活动导航到哪个活动。 - x90
@Stephen,GalleryDetailFragment 在哪个活动中托管? - x90
@Stephen 我明白。但是每个片段都应该托管/附加/连接/属于Activity。我想知道你的片段属于哪个Activity。 - x90
此方法会销毁之前的活动,如果您想保留状态,请参考上面的解决方案。 - Abhi Soni
这是正确的答案。因为选择标记为“解决方案”的答案是一种hack。它可以工作,但这是一种不好的实践,会强制你使用冗余代码。 - VKostenc
显示剩余2条评论

45

您需要在onCreate方法中调用setDisplayHomeAsUpEnabled(true)方法,并重写 onSupportNavigateUp() 方法并在其中调用 onBackPressed()。就是这样,完成了 :)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_help);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

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

为什么?我测试了一下,只需在清单文件中添加android:parentActivityName=".activities.MainActivity",并且在我测试的这个设备上就足够了。 - David
虽然这个方法可以工作,但在手动调用 onBackPressed 之前,请确保您的活动中已设置了 android:parentActivityName。请参阅 https://dev59.com/xmAg5IYBdhLWcg3wDHQ3#24033351。 - Wyck
1
对于Kotlin:override fun onSupportNavigateUp(): Boolean { onBackPressed() return true } - Aathil Ahamed

14

你只需将以下一行代码添加到manifest.xml文件中的活动中。父活动是你想要返回的活动。

    android:parentActivityName=".activities.MainActivity"

10

首先,在对片段进行commit()之前,您需要使用addToBackStack()

@Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
         // Respond to the action bar's Up/Home button
         case android.R.id.home:
             if(getSupportFragmentManager().getBackStackEntryCount()>0)
                getSupportFragmentManager().popBackStack();
             return true;
         }
         return super.onOptionsItemSelected(item);
     } 

3
这是什么,你能解释一下吗? - Wang'l Pakhrin

8

最好且简单的答案是在Manifest文件中添加父Activity名称,这样ActionBar的返回按钮将会起作用。

为此,在Manifest文件的Activity标签下使用以下内容:android:parentActivityName=".MyCustomParentActivity"


3
如果显示了主页按钮,您应该通过 onOptionItemSelected 函数(在您的情况下为箭头)为主页按钮添加一个操作。默认情况下没有任何操作,因此未能工作是完全正常的。请将此函数添加到您的活动中:
 override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when {
            item.itemId == android.R.id.home -> {
                finish()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

1
对我来说,我必须将 mDrawerToggle.setToolbarNavigationClickListener(...) 设置为一个触发后退操作的监听器。否则它什么也不做。这是 ActionBarDrawerToggle 的源代码所示的内容:
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    if (mDrawerIndicatorEnabled) {
      toggle();
    } else if (mToolbarNavigationClickListener != null) {
      mToolbarNavigationClickListener.onClick(v);
    }
  }
});

因此,默认行为实际上是调用我们的监听器,而不进行任何自己的魔法。

1

使用SupportNavigateUp()方法,在该方法中调用onBackPressed


1

这里提供的答案都没有对我起作用。我不得不把 switch 放在 onMenuItemSelected 方法内部。我知道这不是 Android 文档中所述的方法,但它确实有效,所以我想为遇到同样问题的人留下这个提示。我的问题涉及一个 Activity 而不是一个 Fragment,但两者应该基本相同。

class FooActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        getActionBar().setHomeButtonEnabled(true);
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;
        }

        return false;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接