如何在Fragment从后端堆栈返回布局时重用先前创建的视图?

时间:2013-03-25 16:29:01

标签: android view transactions fragment

众所周知,Fragment实例在添加到后台堆栈时不会被销毁(参见:Creating a Fragment)。

我的片段有一个复杂的视图。我的目的是防止在片段从后栈返回到布局时重新创建视图,以便更快地呈现。

我的Fragment扩展类中的代码类似如下:

View firstView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (firstView == null) {
        firstView = inflater.inflate(R.layout.first_view, container, false);
        Button btn_read = (Button)firstView.findViewById(R.id.btn_read);
        btn_read.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                  // do something
            }
        });
    }

    return firstView;
}

我的片段被添加到后台。

然而,当我按“后退”弹出后台时,我得到以下异常。显然,先前在onCreateView中创建的视图仍然附加到某个地方,并且无法重新用于新的父视图。

我理解不遵循使用片段的“一般模式”是不明智的。我只是好奇如何防止重新创建BIG视图以提高Fragment中的性能。

-------------例外---------------

03-25 23:55:38.354: W/dalvikvm(314): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
03-25 23:55:38.354: E/AndroidRuntime(314): Uncaught handler: thread main exiting due to uncaught exception
03-25 23:55:38.445: E/AndroidRuntime(314): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewGroup.addViewInner(ViewGroup.java:1861)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewGroup.addView(ViewGroup.java:1756)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewGroup.addView(ViewGroup.java:1713)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewGroup.addView(ViewGroup.java:1693)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:874)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:697)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1465)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:447)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:164)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.app.Activity.onKeyUp(Activity.java:1863)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.KeyEvent.dispatch(KeyEvent.java:1061)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.app.Activity.dispatchKeyEvent(Activity.java:2043)
03-25 23:55:38.445: E/AndroidRuntime(314):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1631)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2368)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2338)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1641)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.os.Looper.loop(Looper.java:123)
03-25 23:55:38.445: E/AndroidRuntime(314):  at android.app.ActivityThread.main(ActivityThread.java:4363)
03-25 23:55:38.445: E/AndroidRuntime(314):  at java.lang.reflect.Method.invokeNative(Native Method)
03-25 23:55:38.445: E/AndroidRuntime(314):  at java.lang.reflect.Method.invoke(Method.java:521)
03-25 23:55:38.445: E/AndroidRuntime(314):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
03-25 23:55:38.445: E/AndroidRuntime(314):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
03-25 23:55:38.445: E/AndroidRuntime(314):  at dalvik.system.NativeStart.main(Native Method)
03-25 23:55:38.445: I/Process(52): Sending signal. PID: 314 SIG: 3

1 个答案:

答案 0 :(得分:0)

你可以尝试

if (view != null) { 
   ((ViewGroup) view.getParent()).removeView(view);
} else {
   // Create your view
   ...
}

return view