Android片段新实例未调用

时间:2017-03-23 14:10:41

标签: android android-fragments

在我的应用程序中,我必须处理需要大量片段进行实例化的不同情况。

为了更好地维护用户体验,我管理了Fragment的BackStack,有时还管理了一个子片段的backstack。

一切正常,直到用户填写了这个背包的一部分。

现在,如果用户想要进入先前添加到backstack的片段,系统会处理请求Pop Fragments,直到用户请求为止。

这样就不会调用片段的newInstance()方法,因为(我相信)片段是从内存中恢复的。

问题在于:

有时,在我的应用程序中,在不同的地方,我创建了相同片段的实例,但在Fragment.newInstance()中传递了不同的参数;

通过这种方式,我可以以不同的方式使用相同的片段。

但是,如果已经实例化了相同的片段,系统将从BackStack中恢复旧的片段实例。

真实情况:

片段A - >我的片段;

实例A1 ---->我从newInstance获得的实例(参数1);

实例A2 ---->我从newInstance获得的实例(参数2);

在应用程序中有一个DrawerMenu有2个声音,第一个呼叫并显示A1,第二个呼叫并显示A2。

用户打开应用程序,然后单击第一个语音,然后以正确的方式显示A1。

比用户点击第二个声音,A.newInstance(参数2);被调用,但系统从backstack恢复A1,而A1显示而不是A2。

感谢。

修改

我的FragmentManager的事务代码,此方法保留在MainActivity中。

当我想要更改片段时,我调用changeFragment(FragmentA.newIstance(Parameter1),true,true);

布尔参数用于Backstack和动画

public void changeFragment(Fragment frag, boolean saveInBackstack, boolean animate) {
    String backStateName = ((Object) frag).getClass().getName();
    String TAG ="Fragment manager";

    try {
        FragmentManager manager = getSupportFragmentManager();
        boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);

        if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
            //fragment not in back stack, create it.
            FragmentTransaction transaction = manager.beginTransaction();

            if (animate) {
                Log.d(TAG, "Change Fragment: animate");
                transaction.setCustomAnimations(R.anim.fadein,R.anim.fadeout, R.anim.fadein,R.anim.fadeout);
            }

            transaction.replace(R.id.framelayout_container, frag, backStateName);

            if (saveInBackstack) {
                Log.d(TAG, "Change Fragment: addToBackTack " + backStateName);
                transaction.addToBackStack(backStateName);
            } else {
                Log.d(TAG, "Change Fragment: NO addToBackTack");
            }

            transaction.commit();
        } else {
            // AnimationShake(findViewById(R.id.fragment_holder));
        }
    } catch (IllegalStateException exception) {
        Log.w(TAG, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
    }
}

这是ChildFragmentManager的方法,我在片段中使用它,它应该处理其中的其他子片段,我以与之前相同的方式调用它:

public void changeFragmentChild(Fragment frag, boolean saveInBackstack, boolean animate) {
    String backStateName = ((Object) frag).getClass().getName();
    String TAG ="Fragment manager";

    try {
        FragmentManager manager = getChildFragmentManager();
        boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);

        if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
            //fragment not in back stack, create it.
            FragmentTransaction transaction = manager.beginTransaction();

            if (animate) {
                Log.d(TAG, "Change Fragment: animate");
                transaction.setCustomAnimations(R.anim.enter_from_right,R.anim.exit_from_left, R.anim.enter_from_left,R.anim.exit_from_right);
            }

            transaction.replace(R.id.chilcontainer, frag, backStateName);

            if (saveInBackstack) {
                Log.d(TAG, "Change Fragment: addToBackTack " + backStateName);
                transaction.addToBackStack(backStateName);
            } else {
                Log.d(TAG, "Change Fragment: NO addToBackTack");
            }

            transaction.commit();
        } else {
            // AnimationShake(findViewById(R.id.fragment_holder));
        }
    } catch (IllegalStateException exception) {
        Log.w(TAG, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
    }
}

0 个答案:

没有答案