【问题标题】:The specified child already has a parent. You must call removeView() on the child's parent first. (C#)指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。 (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 我刚刚做了。请检查。

标签: c# android view xamarin


【解决方案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 中可能不同):

  1. 获取我需要的孩子的参考。 Grid contentGrid = page.ContentGrid;
  2. 从父级中移除子级(有点悲伤)。在我的情况下,父级是一个名为 MainGrid: page.MainGrid.Children.Remove(contentGrid); 的网格

看起来,在你的情况下,Children 集合 si 的 Remove() 方法称为 RemoveView(),因为它们将控件称为“视图”,我个人讨厌。

【讨论】:

  • 老实说,我不知道从哪里获得参考以及我应该使用什么 Parent。是ImageView 还是AlertDialog
猜你喜欢
  • 2015-09-06
  • 2015-03-20
  • 1970-01-01
  • 2013-10-18
  • 2020-02-16
  • 2014-06-02
相关资源
最近更新 更多