如何阻止 Fragment 的 onCreateView() 方法被调用?

9
所以这是我的代码。'currentFragment'只是一个字段,用于跟踪当前正在显示的内容。这是一个自身就是片段的类(因此我有一个显示片段的片段)。
private void selectNavBarItem(NavbarItem v)
{
    Fragment fragmentToUse = null;

    if (v == setpointsNavItem)
    {
        fragmentToUse = setpointsFragment;
    }
    else if (v == rapidSetupNavItem)
    {
        fragmentToUse = rapidSetupFragment;
    }
    else if (v == outdoorResetNavItem)
    {
        fragmentToUse = outdoorResetFragment;
    }
    else if (v == rampDelayNavItem)
    {
        fragmentToUse = rampDelayFragment;
    }

    if (fragmentToUse != null)
    {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        if (currentFragment != null)
        {
            ft.detach(currentFragment);
        }

        currentFragment = fragmentToUse;

        if (currentFragment.isDetached())
        {
            ft.attach(currentFragment);
        }
        else
        {
            ft.add(R.id.setup_content_holder, currentFragment);
        }

        ft.addToBackStack(null);
        ft.commit();
    }

所有内容看起来都很好,但是所有片段的视图(onCreateView()和onViewCreated())都在重新创建。我希望附加和分离会起作用,但它并没有。我要保留视图的原因是当用户返回时,他们的选择仍然存在。
另一个选择是显示和隐藏,但我不知道如何使其工作,因为拥有此代码的片段具有一个FrameLayout(R.id.setup_content_holder),该布局包含我想要添加的片段,而我不能只添加四个片段并将其中三个隐藏。有一个选项可以添加一个没有容器的片段,但我不知道它应该如何工作。
那么,有什么建议吗?
3个回答

10

尝试这个,它将解决你的碎片视图重新创建问题;

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (mFragmentView != null) {
            ((ViewGroup) mFragmentView.getParent()).removeView(mFragmentView);
            return mFragmentView;
        }

        mFragmentView = inflater.inflate(R.layout.home_fragment, container, false);

        ..... // your remaining code 
}

8
安卓开发者通常会做这个吗? - Eyeball

1

我在这里。

所以我在这里拼凑了一些东西,想知道这是否是一个好主意。我有一个包含视图的片段。视图包含我想要保存的所有内容(当然是短期的 - 这不应该比 RAM 更持久)。当片段调用onCreateView()时,我只需返回已经创建的视图即可。

现在,我遇到了一个问题,即视图没有被片段管理器删除。我在onPause()中添加了一个调用,以确保它从父级中删除。

一切似乎都很正常,但我想确保我没有做什么非常糟糕的事情。我知道Android真的非常希望自己管理其视图生命周期,但我不希望每次都重新创建它们。它们很复杂,我不想处理重新初始化所有子视图的文本/图像/状态。我尝试绕过Android的正常操作程序,会遇到问题吗?

编辑:忘记代码:

public class OutdoorResetFragment extends Fragment
{
private OutdoorResetView view;

public OutdoorResetFragment()
{

}

public void onAttach(Activity activity)
{
    if (view == null || view.getContext() != activity)
    {
        view = new OutdoorResetView(activity);
    }

    super.onAttach(activity);
}

public void onPause()
{
    super.onPause();

    ViewGroup container = (ViewGroup) view.getParent();

    if (container != null)
    {
        container.removeAllViews();
    }
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
        final Bundle savedInstanceState)
{
    return view;
}

public OutdoorResetView getView()
{
    return view;
}
}

1

OnCreateView方法始终在Fragment中调用。

要解决您描述的问题,您真正需要做的是保存片段的状态,然后当它返回时,应用程序将恢复您保存的内容。

例如(在相关的片段类内部):

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceStatePutString("userString", someTextView.getText().toString());
    savedInstanceStatePutInt("userInt", userInt);
    // etc...
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    someTextView.setText(savedInstanceState.getString("userString"));
    userInt = savedInstanceState.getInt("userInt");
}

那应该解决您在片段之间跳转时的问题;当一个片段被推入或拉出堆栈时,应用程序将调用onSaveInstanceState和onRestoreInstanceState。但是,它们不会永久保存!如果您需要更持久的存储,请查看其他选项,如保存到sqlite数据库。

1
唉,我不想使用Bundles——如果我修改字段,它们需要大量的维护,更不用说缺乏编译时检查了。请不要误解我的回答——我相信这是Android希望我这样做的方式。你知道吗,我的新方法(见我的新回答)是否可行? - Mark Herscher

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