指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。 (C#)
Posted
技术标签:
【中文标题】指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。 (C#)【英文标题】:The specified child already has a parent. You must call removeView() on the child's parent first. (C#) 【发布时间】:2016-06-27 10:23:00 【问题描述】:我已经看到了很多类似的问题,但到目前为止,我所看到的都没有解决我的问题(主要是因为它是在 Java 中,而我使用的是 C#)。
protected override void OnCreate(Bundle bundle)
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainV2);
if (IsThereAnAppToTakePictures())
CreateDirectoryForPictures();
btnAdd = FindViewById<Button>(Resource.Id.btnAdd);
btnAdd.Click += DialogAddPhoto;
myFileListAdapter = new ArrayAdapter(this, Resource.Drawable.style_listview);
listViewFiles = FindViewById<ListView>(Resource.Id.listView1);
private void DialogAddPhoto(object sender, EventArgs eventArgs)
// passing intent i.e. REQUEST_CAMERA, SELECT_FILE
问题出在哪里...
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
base.OnActivityResult(requestCode, resultCode, data);
_imageView = new ImageView(this);
btnRemove = FindViewById<Button>(Resource.Id.btnRemove);
if (resultCode == Result.Ok)
if (requestCode == REQUEST_CAMERA)
// ................. //
else if ((requestCode == SELECT_FILE) && (data != null))
android.Net.Uri uri = data.Data;
string imgUri = Convert.ToString(uri);
string[] proj = MediaStore.Images.ImageColumns.Data ;
var cursor = ContentResolver.Query(uri, proj, null, null, null);
var colIndex = cursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
BitmapFactory.Options options = new BitmapFactory.Options InJustDecodeBounds = true ;
BitmapFactory.DecodeFile(cursor.GetString(colIndex), options);
int height = 300;
int width = Resources.DisplayMetrics.WidthPixels;
int outHeight = options.OutHeight;
int outWidth = options.OutWidth;
int inSampleSize = 1;
if (outHeight > height || outWidth > width)
inSampleSize = outWidth > outHeight
? outHeight / height
: outWidth / width;
options.InSampleSize = inSampleSize;
options.InJustDecodeBounds = false;
App.bm = BitmapFactory.DecodeFile(cursor.GetString(colIndex), options);
System.IO.MemoryStream mem = new System.IO.MemoryStream();
App.bm.Compress(Bitmap.CompressFormat.Png, 100, mem);
//byte[] byteArray = mem.ToArray();
_imageView.SetImageBitmap(App.bm);
App.bm = null;
GC.Collect();
myFileListAdapter.Add(imgUri);
myFileListAdapter.NotifyDataSetChanged();
setListViewHeightBasedOnChildren(listViewFiles);
listViewFiles.ItemClick += (object sender, ItemClickEventArgs e) =>
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetTitle("Preview");
builder.SetView(_imageView);
builder.SetCancelable(false);
builder.SetPositiveButton("Cancel", (senderAlert, args) => );
builder.SetNegativeButton("Delete?", (senderAlert, args) =>
Java.Lang.Object toRemove = myFileListAdapter.GetItem(e.Position);
myFileListAdapter.Remove(toRemove);
myFileListAdapter.NotifyDataSetChanged();
setListViewHeightBasedOnChildren(listViewFiles);
);
builder.Show();
;
这是罪魁祸首。
builder.SetView(_imageView);
我试过这样做,但仍然遇到同样的错误。
builder.SetView(null);
builder.SetView(_imageView);
它的作用是在从图库中选择或添加图像后,Uri
被添加到列表中 (ListView
)。单击该项目,将出现一个警报对话框,其中可以看到图像 (_imageView
)。单击Cancel
并在图库中的Deleting and Adding
之后查看Uri
图像后发生错误。
我见过的所有解决方案都使用 Inflate,老实说,我不知道如何将它合并到我的代码中,因为 imageview 取决于动态值(从图库中导入的图像)。
请注意,我使用的是 Xamarin Android。
追踪:
06-27 17:51:54.434 E/mono-rt (16678): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
06-27 17:51:54.434 E/mono-rt (16678): at android.view.ViewGroup.addViewInner(ViewGroup.java:3430)
06-27 17:51:54.434 E/mono-rt (16678): at android.view.ViewGroup.addView(ViewGroup.java:3301)
06-27 17:51:54.434 E/mono-rt (16678): at android.view.ViewGroup.addView(ViewGroup.java:3277)
06-27 17:51:54.434 E/mono-rt (16678): at com.android.internal.app.AlertController.setupView(AlertController.java:416)
06-27 17:51:54.434 E/mono-rt (16678): at com.android.internal.app.AlertController.installContent(AlertController.java:244)
06-27 17:51:54.434 E/mono-rt (16678): at android.app.AlertDialog.onCreate(AlertDialog.java:337)
06-27 17:51:54.434 E/mono-rt (16678): at android.app.Dialog.dispatchOnCreate(Dialog.java:355)
06-27 17:51:54.434 E/mono-rt (16678): at android.app.Dialog.show(Dialog.java:260)
06-27 17:51:54.434 E/mono-rt (16678): at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
06-27 17:51:54.434 E/mono-rt (16678): at mono.android.widget.AdapterView_OnItemClickListenerImplementor.n_onItemClick(Native Method)
06-27 17:51:54.434 E/mono-rt (16678): at mono.android.widget.AdapterView_OnItemClickListenerImplementor.onItemClick(AdapterView_OnItemClickListenerImplementor.java:29)
06-27 17:51:54.434 E/mono-rt (16678): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
06-27 17:51:54.434 E/mono-rt (16678): at android.widget.AbsListView.performItemClick(AbsListView.java:1128)
06-27 17:51:54.434 E/mono-rt (16678): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2815)
06-27 17:51:54.434 E/mono-rt (16678): at android.widget.AbsListView$1.run(AbsListView.java:3574)
06-27 17:51:54.434 E/mono-rt (16678): at android.os.Handler.handleCallback(Handler.java:800)
06-27 17:51:54.434 E/mono-rt (16678): at android.os.Handler.dispatchMessage(Handler.java:100)
06-27 17:51:54.434 E/mono-rt (16678): at android.os.Looper.loop(Looper.java:194)
06-27 17:51:54.434 E/mono-rt (16678): at android.app.ActivityThread.main(ActivityThread.java:5371)
06-27 17:51:54.434 E/mono-rt (16678): at java.lang.reflect.Method.invokeNative(Native Method)
06-27 17:51:54.434 E/mono-rt (16678): at java.lang.reflect.Method.invoke(Method.java:525)
06-27 17:51:54.434 E/mono-rt (16678): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
06-27 17:51:54.434 E/mono-rt (16678): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
06-27 17:51:54.434 E/mono-rt (16678): at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
您能否将堆栈跟踪添加到您的答案中? @YumeYume 我刚刚做了。请检查。 【参考方案1】:图像视图已经分配给一个父创建一个新的图像视图并设置它
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetTitle("Preview");
var temp= new ImageView(this);
temp.SetImageBitmap(App.bm);
builder.SetView(temp);
builder.SetCancelable(false);
builder.SetPositiveButton("Cancel", (senderAlert, args) => );
builder.SetNegativeButton("Delete?", (senderAlert, args) =>
Java.Lang.Object toRemove = myFileListAdapter.GetItem(e.Position);
myFileListAdapter.Remove(toRemove);
myFileListAdapter.NotifyDataSetChanged();
setListViewHeightBasedOnChildren(listViewFiles);
);
builder.Show();
;
【讨论】:
这似乎有效,我不再收到错误但添加另一个图像后,查看图像的对话框正在重复。例如,我添加了一张照片,然后我查看了它,删除它后,我添加了另一张照片。当我查看它然后单击取消时,之前添加的图像的对话框就在那里。这让我很困惑。 还有一个是我添加了很多照片,当我一张一张点击时,对话框中只有最新添加的照片。 请使用 -= 取消绑定事件处理程序,方法与使用 += 添加的方式相同,并在删除时关闭对话框 抱歉回复晚了。我应该取消绑定什么事件处理程序?像这样:listViewFiles.ItemClick -= (object sender, ItemClickEventArgs e)
?似乎也没有选择解雇AlertDialog.Builder
?我是新手,所以希望你不要介意。
listViewFiles.ItemClick += ClickHandler;.... ClickHandler(object sender, ItemClickEventArgs e)... listViewFiles.ItemClick -= ClickHandler【参考方案2】:
TLDR;
我在 WPF 中遇到了类似的问题。我如何解决它的步骤(代码用于 WPF,API 在 XAMARIN 中可能不同):
-
获取我需要的孩子的参考。
Grid contentGrid = page.ContentGrid;
从父级中移除子级(有点悲伤)。在我的情况下,父级是一个名为 MainGrid
: page.MainGrid.Children.Remove(contentGrid);
的网格
看起来,在你的情况下,Children
集合 si 的 Remove()
方法称为 RemoveView()
,因为它们将控件称为“视图”,我个人讨厌。
【讨论】:
老实说,我不知道从哪里获得参考以及我应该使用什么 Parent。是ImageView
还是AlertDialog
?以上是关于指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。 (C#)的主要内容,如果未能解决你的问题,请参考以下文章
我继续收到错误消息“指定的孩子已经有一个父母。您必须首先在该孩子的父母上调用removeView()(Android)
冲突的 Android 错误消息:指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()
指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()
Fragments - 指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()
收到错误“指定的孩子已经有父母。您必须先在孩子的父母上调用 removeView()。”? [复制]
Android - ArrayAdapter<LinearLayout> :指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()