【问题标题】:Back button and ActionbarUpButton close app instead of going back后退按钮和 ActionbarUpButton 关闭应用程序而不是返回
【发布时间】:2016-02-07 15:28:30
【问题描述】:

在我的 MainActivity 中,我有一个 SlidingTabBar,并从这些选项卡(片段)中打开某些事件的其他活动(如 FAB-onClick)。现在,当我在打开的 Activity 上并按下设备上的后退按钮或操作栏中的 HomeAsUp(后退)按钮时,我想从我打开另一个 Activity 的位置返回 MainActivity 上的 Fragment,但是应用程序刚刚关闭。

我没有任何 onBackPressed 方法,也没有在我打开的活动中的任何地方调用 finsish()。 我只是根据 Fragment 的意图调用它们:

Intent intent = new Intent(getActivity(), OfferActivity.class);
startActivity(intent);

我的 MainActivity 中有这个方法,因为我希望能够使用返回按钮退出应用程序:

@Override
public void onBackPressed() {
   finish();
}

我也有一个 LoginActivity,我用这种方式调用 MainActivity(它是一个 FacebookLogin,所以在第一次打开应用程序时只需要一次):

Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

如果您需要任何其他代码,请告诉我:)

编辑:这是我如何在 MainActivity 中将片段添加到 TabLayout 的代码:

private void setupViewPager(ViewPager viewPager) {

    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());

    adapter.addFragment(new NewsFragment(), "NEWS");
    adapter.addFragment(new ProfileFragment(), "PROFILE");
    adapter.addFragment(new NotificationFragment(), "NOTIF");
    adapter.addFragment(new AboutFragment(), "ABOUT");

    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        //return mFragmentTitleList.get(position);

        // null -> just use icons
        return null;
    }
}

编辑 2:这是我的清单:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:name=".adapter.AppController">
<activity
        android:name=".main.LoginActivity"
        android:label="friendlyride">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>
<activity
        android:name=".main.MainActivity"
        android:label="friendlyride">
</activity>
<activity
        android:name=".main.OfferActivity"
        android:label="Offer ride"
        android:parentActivityName=".main.MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".main.MainActivity"
            />
</activity>
</application>

main.MainActivity 是我的 TabLayout 所在的位置,而 main.OfferActivity 是我想从 Fragment 打开的位置。 main.LoginActivity 具有意图过滤器,因为它是我尚未登录时的第一个 Activity(如果此意图过滤器很重要,我现在不知道 :))

最终编辑: 我刚刚发现了问题。我使用 NO_HISTORY 和 CLEAR_TOP 标志从我的 LoginActivity 打开 MainActivity(从那里打开其他所有内容)。显然这些标志也用于 MainActivity 上的 Intent,即使我没有设置它们。我不知道在以下活动中“记住”了标志,即使我使用没有标志的新 Intent。感谢您的所有回答。 :)

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    我会再试一次,因为我没有仔细阅读问题。

    所以如果你有活动 A 启动活动 B,在你的 AndroidManifest.xml 中你应该有:

    <manifest>
      <application>
         <activity android:name=".ActivityA" ...etc >
         <activity
            android:name=".ActivityB"
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="my.package.name.ActivityA" />
        </activity>
    ... closing tags
    

    注意,Activity B 中的android.support.PARENT_ACTIVITY 指向my.package.name.ActivityA

    如果这没有帮助,您能否提供您的 AndroidManifest.xml 文件?

    【讨论】:

    • 再次感谢,我的清单看起来很相似。我添加了我认为重要的部分。如果您需要更多,请告诉我:)
    【解决方案2】:

    你应该这样做。

    在您的清单文件中定义每个活动的父活动,这将是用户按下后退按钮时将调用的活动,如果没有则关闭应用程序。

    所以做这样的事情。

    <activity
                android:name="com.youtpath.yourActivity"
                android:launchMode="singleTask">
                <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                  android:value="com.yourPath.theMainActivityActivity" />
    

    这样就解决了返回的问题,但是你必须添加“singleTask”launchMode参数,这样你的MainActivity只有一个实例,避免在你按下返回时创建另一个MainActivity。

    关于片段,FragmentManager 是一个 Activity 字段,而不是来自应用程序,因此您不能从新的 Activity 调用片段回堆栈,因为没有任何。

    您的问题不是片段之间的导航,而是从活动中导航。

    希望它能解决问题。

    :)

    【讨论】:

    • 感谢您的回答。我刚刚发现了问题。我使用 NO_HISTORY 和 CLEAR_TOP 标志从我的 LoginActivity 中打开了 MainActivity(从那里打开其他所有内容)。显然这些标志也用于 MainActivity 上的 Intent,即使我没有设置它们。 :)
    【解决方案3】:

    您需要将您的 Fragment 访问添加到 backstack。

    Providing Proper Back Navigation

    特别是 Fragments 的实现返回导航:

    getSupportFragmentManager().beginTransaction()
                           .add(detailFragment, "detail")
                           // Add this transaction to the back stack
                           .addToBackStack()
                           .commit();
    

    【讨论】:

    • 谢谢,我已经查过了,但是当我不使用事务时,我不知道如何使用它。如果您能进一步帮助我,我已经添加了如何将片段添加到 TabLayout 的代码。 :)
    • 在manifest中建立父activity,不解决问题?
    • 如前所述,我在上面的代码中添加了我的片段,所以我没有使用事务。所以我不知道如何调用 popBackStack 来回到 Fragment,因为我从来没有将它添加到 backstack。 :)
    • 对不起,我读得太快了。我虽然问题是从片段而不是从活动中返回的。 @DanielOrdoñez 是正确的 - 试试看。
    猜你喜欢
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多