Android Fragments - 指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23149981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fragments - The specified child already has a parent. You must call removeView() on the child's parent first
提问by Vivek
I am getting this error. I tried many solutions but I coudnt solve this. Help me! I need to add the surface view and the button to the activity using fragments.
我收到此错误。我尝试了很多解决方案,但我无法解决这个问题。帮我!我需要使用片段将表面视图和按钮添加到活动中。
CamActivity.java:
凸轮活动.java:
public class CamActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cam);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if(fragment == null) {
fragment = new CamFragment();
fm.beginTransaction()
.add(R.id.fragmentContainer, fragment)
.commit();
}
}
}
CamFragment.java:
CamFragment.java:
public class CamFragment extends Fragment {
private static final String TAG = "CamFragment";
private Camera mCamera;
private SurfaceView mSurfaceView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.camera_fragment, parent);
Button capturePic = (Button)v.findViewById(R.id.img_capture);
capturePic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().finish();
}
});
mSurfaceView = (SurfaceView)v.findViewById(R.id.surfaceView1);
return v;
}
}
Error:
错误:
04-18 13:24:12.735: E/AndroidRuntime(6321): FATAL EXCEPTION: main
04-18 13:24:12.735: E/AndroidRuntime(6321): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pack.camdictionary/com.pack.camdictionary.CamActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1728)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1747)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread.access00(ActivityThread.java:155)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:993)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.os.Handler.dispatchMessage(Handler.java:130)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.os.Looper.loop(SourceFile:351)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread.main(ActivityThread.java:3814)
04-18 13:24:12.735: E/AndroidRuntime(6321): at java.lang.reflect.Method.invokeNative(Native Method)
04-18 13:24:12.735: E/AndroidRuntime(6321): at java.lang.reflect.Method.invoke(Method.java:538)
04-18 13:24:12.735: E/AndroidRuntime(6321): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
04-18 13:24:12.735: E/AndroidRuntime(6321): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:659)
04-18 13:24:12.735: E/AndroidRuntime(6321): at dalvik.system.NativeStart.main(Native Method)
04-18 13:24:12.735: E/AndroidRuntime(6321): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.view.ViewGroup.addViewInner(ViewGroup.java:2007)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.view.ViewGroup.addView(ViewGroup.java:1902)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.view.ViewGroup.addView(ViewGroup.java:1859)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.view.ViewGroup.addView(ViewGroup.java:1839)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1166)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.Activity.performStart(Activity.java:3837)
04-18 13:24:12.735: E/AndroidRuntime(6321): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1701)
04-18 13:24:12.735: E/AndroidRuntime(6321): ... 11 more
回答by user3390963
Try to replace
尝试更换
View v = inflater.inflate(R.layout.camera_fragment, parent);
With
和
View v = inflater.inflate(R.layout.camera_fragment, parent, false);
or
或者
View v = inflater.inflate(R.layout.camera_fragment, null);
回答by Bharat Kul Ratan
This question had already been answered but still I would like to add the reason for adding falseas the third parameter.
这个问题已经得到了回答,但我仍然想添加添加false作为第三个参数的原因。
The inflate() method takes three arguments:
- The resource ID of the layout you want to inflate.
- The ViewGroup to be the parent of the inflated layout. Passing the container is important in order for the system to apply layout parameters to the root view of the inflated layout, specified by the parent view in which it's going.
- A boolean indicating whether the inflated layout should be attached to the ViewGroup (the second parameter) during inflation. (In this case, this is false because the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout.)
inflate() 方法接受三个参数:
- 要膨胀的布局的资源 ID。
- 要成为膨胀布局的父级的 ViewGroup。传递容器对于系统将布局参数应用于膨胀布局的根视图非常重要,该根视图由其所在的父视图指定。
- 一个布尔值,指示在膨胀期间是否应将膨胀的布局附加到 ViewGroup(第二个参数)。(在这种情况下,这是错误的,因为系统已经将膨胀的布局插入到容器中——传递 true 将在最终布局中创建一个冗余的视图组。)
Source: http://developer.android.com/guide/components/fragments.html
来源:http: //developer.android.com/guide/components/fragments.html
回答by Satheesh
I am using API 26.0.2 and in my case, the crash was happening because of custom animations set for my fragments. Commenting out the call to set the custom animation, fixed the issue.
我正在使用 API 26.0.2,在我的情况下,崩溃是由于为我的片段设置的自定义动画而发生的。注释掉设置自定义动画的调用,修复了问题。
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
回答by Irshu
In my case, I was doing the setTransition()
during the FragmentTransaction
. Below code worked for me:
就我而言,我setTransition()
在FragmentTransaction
. 下面的代码对我有用:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
if(this::rootView.isInitialized){
if(rootView.getParent() != null){
(rootView.getParent() as ViewGroup).endViewTransition(rootView)
}
return this.rootView
}
...
}
This probably happens when you repeatedly switch between fragments, that the view does not get time to really detach from the parent due to the ongoing transition.
当您在片段之间反复切换时,可能会发生这种情况,由于正在进行的转换,视图没有时间真正与父级分离。
回答by AnhSang
I also met this problem, and this is my solution. it's very easy
我也遇到了这个问题,这就是我的解决方案。这很容易
View v;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (v == null) {
v = inflater.inflate(R.layout.camera_fragment, container);
} else {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null) {
parent.removeView(v);
}
}
return v;
}
Hope to be useful to you
希望对你有用
回答by Pai-Hsiang Huang
Just for your reference. It seems to be an issue in the Android SDK.
仅供参考。这似乎是 Android SDK 中的一个问题。
I have the same situation like @Satheesh had with the SDK version: 27.0.2 and trying to remove the setCustomAnimation seems works. But to remove the setCustomAnimations requires lots of change to make for me, I'd prefer to keep the custom animation. What I have done is to upgrade the SDK to the latest version which is 27.1.1 for now. And it works for me.
我的情况与@Satheesh 与 SDK 版本相同:27.0.2 并尝试删除 setCustomAnimation 似乎有效。但是要删除 setCustomAnimations 需要对我进行大量更改,我更愿意保留自定义动画。我所做的是将 SDK 升级到最新版本,目前是 27.1.1。它对我有用。
回答by Muhaiminur Rahman
Might be Helpfull
可能有帮助
View customView1;
inflater= (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
customView1= inflater.inflate(R.layout.edit_custom_alert_window, null);
try {
if(customView2.getParent()!=null)
((ViewGroup)customView2.getParent()).removeView(customView2);
}catch (Exception e){
}
回答by Sayed Abolfazl Fatemi
Specify Id
for parent and child element, especially for custom views, in xml
file may solve problem.
Id
在xml
文件中指定父元素和子元素,尤其是自定义视图,可能会解决问题。
回答by maddy d
try this.
尝试这个。
((CamActivity)getActivity()).finish();