标签: fragment-backstack

Android 导航组件 - 向上导航打开相同的片段

我在执行时遇到问题

findNavController(R.id.main_nav_host).navigateUp()
Run Code Online (Sandbox Code Playgroud)

或者

findNavController(R.id.main_nav_host).popBackStack()
Run Code Online (Sandbox Code Playgroud)

它不会返回到 backstack 中的最后一个片段,而是重新打开/导航到同一/当前片段。

有人可以指出我为什么会发生这种情况的正确方向吗?

导航图:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/main_navigation_root"
            app:startDestination="@+id/dest_main">

    <fragment
            android:id="@+id/dest_main"
            android:name="com.example.popularmovies.ui.main.views.MainMoviesFragment"
            android:label="@string/home"
            tools:layout="@layout/fragment_main_movies">

        <action
                android:id="@+id/action_dest_main_to_dest_movie_details"
                app:destination="@+id/dest_movie_details"
                app:enterAnim="@anim/slide_in_right"
                app:exitAnim="@anim/slide_out_left"
                app:popEnterAnim="@anim/slide_in_left"
                app:popExitAnim="@anim/slide_out_right" />

    </fragment>

    <fragment
            android:id="@+id/dest_movie_details"
            android:name="com.example.popularmovies.ui.details.movie.view.MovieDetailsFragment"
            android:label="@string/movie_details"
            tools:layout="@layout/fragment_movie_details"/>

</navigation>
Run Code Online (Sandbox Code Playgroud)

主活动布局:

<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <fragment
            android:id="@+id/main_nav_host"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/main_navigation"/>

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

主要活动:

class MainActivity : AppCompatActivity(), HasSupportFragmentInjector {

    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>

    private lateinit var appBarConfiguration: AppBarConfiguration

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

        initNavUi()
    }

    override fun onBackPressed() …
Run Code Online (Sandbox Code Playgroud)

android kotlin fragment-backstack android-architecture-navigation

9
推荐指数
1
解决办法
3813
查看次数

无论如何交换或重新排序片段BackStack条目?

我正在创建多个片段应用程序,这需要轻松更改片段选项卡,必须保留其BackStack条目.在用户点击片段必须立即弹出.我认为重新排序BackStack是最好的选择.有谁知道如何重新订购BackStack?

我有5个片段A,B,C,D,E.如果用户打开片段,如A ---> B ---> C ---> D ---> E. 使用默认的后栈,后退键可以正常工作.但是当用户打开A ---> B ---> C ---> D ---> E ---> B.此后如果用户单击后退,默认后退堆栈将转到A.

android instance android-fragments fragment-backstack

8
推荐指数
1
解决办法
940
查看次数

如果不存在,如何将BackStackEntry添加到BackStack

我已经为我的片段添加了自定义键盘,现在我想在背面按下时实现关闭键盘.

class CustomKeyboard
{
    public void init(Context context) {
        //...

        FragmentManager fragmentManager = ((Activity) context).getFragmentManager();
        boolean fragmentPopped = fragmentManager.popBackStackImmediate(TAG, 0);
        if (!fragmentPopped) {
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.addToBackStack(TAG);
            fragmentTransaction.commit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

init每次屏幕旋转时都会出现问题,因为我创建了CustomKeyboardpublic void onActivityCreated(final Bundle savedInstanceState)

fragmentPopped=false 每次都可以将CustomKeyboard添加到BackStack中多次.

我的问题:
如果不使用getBackStackEntryCount()方法,是否可以将BackStackEntry添加到BackStack ?

android back-stack fragment-backstack

8
推荐指数
1
解决办法
629
查看次数

防止同一碎片堆叠多次(addToBackStack)

我有一个Activity与三个片段可以打电话给他们一个,Ç.Fragment 一个被称为在活动onCreate().

FragmentA fragA = new FragmentA();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.activity2_layout, fragA, "A");
transaction.commit();
Run Code Online (Sandbox Code Playgroud)

当按下某些按钮时,会被片段BC替换,并且FragmentTransaction会调用addToBackStack().

FragmentB fragB = new FragmentB(); //or C
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.activity2_layout, fragB, "B");  //or C
transaction.addToBackStack("B"); //or C
transaction.commit();
Run Code Online (Sandbox Code Playgroud)

但是让我说我连续三次打电话给Fragment B,我怎么能阻止它自己堆叠呢?同时我希望这是可能的:B调用> C调用> B调用 - 但是当我尝试返回时我希望B只打开一次(C < B)而不是(B < C < B) .所以基本上删除第一个backStack与新的.

android fragment android-fragments back-stack fragment-backstack

7
推荐指数
1
解决办法
6218
查看次数

Android Fragment未添加到Back Stack

我正在做一个基于NavigationDrawer的应用程序.我有一个如下所示的层次结构

NavigationDrawer - > RootFragment(未添加到后面的堆栈) - >详细信息片段(添加到后台堆栈)

现在,我试图通过按后退按钮尝试退出应用程序时向用户显示一条消息.这是我正在使用的代码.

@Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 0) {
            getFragmentManager().popBackStack();
        }
        else if (getFragmentManager().getBackStackEntryCount() == 0) {
            new AlertDialog.Builder(this)
                    .setMessage("Are you sure you want to exit?")
                    .setCancelable(false)
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            MainActivity.this.finish();
                        }
                    })
                    .setNegativeButton("No", null)
                    .show();

        }
        else
        {
            super.onBackPressed();
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我从详细信息片段中单击后退按钮(添加到后台堆栈)时,我收到警报消息.相反,我会回到根片段.

但是,如果我像这样更新代码,按后退按钮会将用户带回到根视图.所以它看起来像getFragmentManager().getBackStackEntryCount()即使将详细片段添加到后台堆栈也是零.

@Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 0) {
            getFragmentManager().popBackStack();
        }
        else
        {
            super.onBackPressed();
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是我从rootFragment调用详细信息片段的方法.

FragmentManager …
Run Code Online (Sandbox Code Playgroud)

android android-fragments fragmenttransaction fragment-backstack

7
推荐指数
1
解决办法
1552
查看次数

Android - 后退按钮和片段后台无法正常工作

我正在开发一个带有片段FragmentActivity的基于片段的简单应用程序.应用程序的每个"屏幕"都包含在一个片段中,所有片段都会在应用程序启动时添加到容器布局中.

// Set up fragments in Main Activity
fragMan = getFragmentManager();
FragmentTransaction ft = fragMan.beginTransaction();
ft.add(R.id.fragment_container, settingsFragment);
ft.add(R.id.fragment_container, mapFragment);
ft.add(R.id.fragment_container, tracksFragment);
ft.add(R.id.fragment_container, waypointsFragment);
ft.commit();
Run Code Online (Sandbox Code Playgroud)

通过隐藏当前可见的片段,然后显示适当的片段来完成转换.

ft = fragMan.beginTransaction();
ft.show(mapFragment);
ft.addToBackStack(null);
ft.commit();
Run Code Online (Sandbox Code Playgroud)

这一切都运行正常,但是当按下后退按钮时,应用程序退出,无论哪个屏幕可见或先前的事务已添加到后栈.

我已经检查过以确保后端堆栈正确累积记录并尝试了许多不同的转换方法变体,例如替换片段而不是隐藏/显示它们,创建片段的新实例而不是将它们存储在变量中等等.正如我所知,我的代码与我能找到的所有教程和示例相匹配,我甚至无法找到任何类似问题/类似问题的例子,大概是因为标准实现"只适用于其他人".

我怀疑它可能是应用程序级别的问题,例如我的清单中的属性(我已经非常彻底地调查过)或者我的应用程序设置方式固有的东西,这会阻止后退按钮正常运行.我可以覆盖onBackPressed来手动处理转换,但这似乎是一个非常难看的解决方法.关于为什么这可能没有按预期行事的任何想法?顺便说一句,这是运行Jelly Bean的Nexus 7.

android android-fragments fragment-backstack

6
推荐指数
1
解决办法
5711
查看次数

使用片段/工具栏返回导航

我现在正在摸着这个......我有一个ActionBarActivity加载一个初始Fragment- 原始菜单在活动中膨胀.现在,我有一个导航栏,当选择一个项目时,它会加载一个不同的片段并将其添加到backstack.

当我这样做时,我想设置几件事:

  1. 将主页设置为向上指示符
  2. 使主活动中的选项菜单无效
  3. 对于Fragment,Set的选项为true
  4. 确保向上指示器正确导航回原始片段

发生了一些比较奇怪的事情 - 向上指示器仅出现一次并且不像后退按钮那样,虽然我已经使新菜单无效并且充气,新菜单会附加到原始活动菜单.

编辑:好吧,我已经解决了追加的问题-忘了加menu.clear()onCreateOptionsMenu方法.

我的导航抽屉布局包含onClick所有菜单项的方法,这些方法会触发另一个片段的加载:

public void navItemClick(View view) {

        switch (view.getId()) {
            case R.id.ripSMS:
                mNavigationDrawer.toggleHome(false);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                FragmentTransaction mTrans = getSupportFragmentManager().beginTransaction();
                mTrans.replace(R.id.voiceover_frame_layout,new MessageFragment(),"main_ui")
                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack("msg").commit();
                break;
            case R.id.ripEmail:
                break;
            case R.id.ripSettings:
                break;
        }

        mNavigationDrawer.closeDrawer();
    }
Run Code Online (Sandbox Code Playgroud)

toggleHome:

public void toggleHome(boolean show) {
        mDrawerToggle.setDrawerIndicatorEnabled(show);

        if (!show) {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        } else {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        }
    }
Run Code Online (Sandbox Code Playgroud)

触发项目后,onCreate包含invalidate和hasOptions代码:

@Override
public void onCreate(Bundle savedInstanceState) { …
Run Code Online (Sandbox Code Playgroud)

android fragment android-actionbaractivity android-toolbar fragment-backstack

6
推荐指数
2
解决办法
2万
查看次数

使用Backstack时TabLayout ViewPager不加载

我在我的一个片段中使用TabLayout,并使用viewPager在标签下方的两个片段之间切换.

当我单击其中一个较低片段中的FAB时,我加载一个新片段(用于输入).

但是 - 当我按下BACK按钮时,TabLayout会显示但没有任何一个较低的片段(由页面表示).

那么我做错了什么?

  • 是否有更好的方式来交换片段
  • 有没有办法按后退按钮并返回正在显示的viewPager页面?

在FAB点击之前来自BackStack 使用TabLayout的片段:CustomTemplatesFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view =  inflater.inflate(R.layout.fragment_custom_templates, container, false);
    final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
    tabLayout.addTab(tabLayout.newTab().setText(R.string.macro_tab));
    tabLayout.addTab(tabLayout.newTab().setText(R.string.lifestyle_tab));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    final ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
    final CustomTemplatesPagerAdapter adapter = new CustomTemplatesPagerAdapter
            (getFragmentManager(), tabLayout.getTabCount());
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void …
Run Code Online (Sandbox Code Playgroud)

android android-fragments back-stack fragment-backstack android-tablayout

6
推荐指数
1
解决办法
2864
查看次数

在片段中的 onResume 期间执行 popBackStackImmediate 时避免 IllegalStateException

我有一个带有片段的活动,以及该活动中用于管理片段的两个简单方法:pushFragmentImmediate()popFragmentImmediate()

\n\n
public void pushFragmentImmediate(Fragment fragment) {\n    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\n    transaction.replace(R.id.fragment_container, fragment)\n            .addToBackStack(null)\n            .commitNow();\n}\n\npublic void popFragmentImmediate() {\n    getSupportFragmentManager().popBackStackImmediate();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这些事务必须立即执行,因为遗留代码依赖于始终保持最新的返回堆栈。

\n\n

现在,如果满足某些条件,我会Fragment弹出一个窗口:onResume

\n\n
@Override\npublic void onResume() {\n    super.onResume();\n    if (condition) {\n        ((Main) getActivity()).popFragment();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会产生错误。\n可以在不更改为 的情况下避免此错误popStackImmediate()popBackStack()popBackStackImmediate()或者当它不会返回错误时我可以转移到其他阶段吗?或者我以错误的方式思考这个问题?

\n\n

完整轨迹:

\n\n
java.lang.RuntimeException: Unable to resume activity {se.esillen.testproject/se.esillen.testproject.Main}: java.lang.IllegalStateException: FragmentManager is already executing transactions\n                                                           at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3433)\n                                                           at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3473)\n                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2736)\n                                                           at android.app.ActivityThread.-wrap12(ActivityThread.java)\n                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1481)\n                                                           at android.os.Handler.dispatchMessage(Handler.java:102)\n                                                           at android.os.Looper.loop(Looper.java:179)\n …
Run Code Online (Sandbox Code Playgroud)

android android-fragments fragmentmanager fragment-backstack

6
推荐指数
0
解决办法
1709
查看次数

体系结构导航组件:每次都会调用onCreateView

每次创建片段实例并在按下时重新加载。

如何克服这个问题?

导航控制器中无法具有适当的后置堆栈是一个巨大的生产率问题。希望这是缺少功能或变通是故意... IMO这是一个必须具备的,并已被宜早不宜迟介绍(但是:https://issuetracker.google.com/issues/109856764我们将不会被允许交易类型的自定义(如隐藏/显示等)在可预见的未来。):(

导航框架很不错,但是,它每次都会创建片段的视图

有人有解决方案吗?

我的代码是使用导航进行导航

object NavigationHelper : Navigational {


override fun moveDownWithPop(view: View,id: Int,popStackId: Int) {
    Navigation.findNavController(view).navigate(id,
            null,
            NavOptions.Builder()
                    .setPopUpTo(popStackId,
                            true).build()
    )
}

override fun moveDownWithDataPop(view: View,id: Int,popStackId: Int,bundle : Bundle) {
    Navigation.findNavController(view).navigate(id,
            bundle,
            NavOptions.Builder()
                    .setPopUpTo(popStackId,
                            true).build()
    )
}

override fun moveUp(view: View) {
    Navigation.findNavController(view).navigateUp()
}

override fun moveDown(view: View,id: Int) {
    Navigation.findNavController(view).navigate(id)
}

override fun moveDown(view: View,id: Int,args : Bundle) {
    Navigation.findNavController(view).navigate(id,args)
}

fun navigateGraph(graphId : Int,context : Context){
    var finalHost: NavHostFragment? …
Run Code Online (Sandbox Code Playgroud)

android fragment-backstack android-architecture-navigation androidx

6
推荐指数
1
解决办法
914
查看次数