3

众所周知,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;
}

我的 Fragment 被添加到后堆栈中。

但是,当我通过按“返回”弹出返回堆栈时,出现以下异常。显然,之前在 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
4

1 回答 1

0

你可以试试

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

return view
于 2014-05-15T11:21:21.700 回答