如何防止片段的onCreateView()被调用?

时间:2014-01-14 01:44:48

标签: android android-fragments android-framework

所以这是我的代码。 '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 个答案:

答案 0 :(得分:9)

试试这个,这将解决你的片段视图创建问题;

 @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 
}

答案 1 :(得分:1)

OnCreateView方法总是在片段中调用。

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

e.g。 (在有问题的片段类中):

@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数据库。

答案 2 :(得分:1)

OP在这里。

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

现在,我遇到了片段管理器没有删除View的问题。我在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;
}
}