Search code examples
c#androidxamarinviewrendering

ViewRenderer.SetNativeControl - The specified child already has a parent


I'm tryed to use this renderer:

using System;
using Android.Content;
using Android.Views;
using Android.Widget;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(AutoComplete), typeof(xmr_cross_test.Custom_controls.AutoCompleteRenderer))]
namespace xmr_cross_test.Custom_controls
{
    public class AutoCompleteRenderer : ViewRenderer<AutoComplete, AutoCompleteTextView>
    {
        public AutoCompleteRenderer()
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<AutoComplete> e)
        {
            base.OnElementChanged(e);
            AutoComplete autocompletview = (AutoComplete)this.Element;

            var inflatorservice = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
            var containerView = inflatorservice.Inflate(Resource.Layout.autocomplete_entry, null, false);

            var autoCompleteTextView = containerView.FindViewById<AutoCompleteTextView>(Resource.Id.autocomplete_textview);
            var autoCompleteOptions = new String[] { "Hello", "Hey", "Bonjour" };
            var adapter = new ArrayAdapter<String>(Context, Resource.Layout.list_item, autoCompleteOptions);
            autoCompleteTextView.Hint = "e.g. Hey";
            autoCompleteTextView.Adapter = adapter;
            autoCompleteTextView.TextChanged += (sender, args) =>
            {
                autocompletview.AutoCompleteText = autoCompleteTextView.Text;
            };

            if (e.OldElement == null)
            {
                // perform initial setup
                base.SetNativeControl(autoCompleteTextView); //exception here
            }
        }
    }
}

But got an exception on binding::

Java.Lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

What is child in this case and how to fix it?

PS: may add reffered in code resources and AutoComplete class if it required.


Solution

  • The 'child' referred to is autoCompleteTextView

    You create the auto complete in XML (and then find it with findViewById). That means the auto complete is already attached to the XML tree. It's parent is the view group it is nested in.

    when you call base.SetNativeControl(autoCompleteTextView); you are trying to add the same view to a second place in the tree and just like a real (wooden) tree in nature the same leaf can't grow from two branches at once.

    Your options are remove from it's existing parent using a bad hacky routine:

    autoCompleteTextView.RemoveFromParent(); //xamarin
    

    Which is the equivalent of the following code on native Android:

    autoCompleteTextView.getParent().removeView(base);
    

    OR create the autocomplete programmatically and then attach it as you are already trying

    (OR perhaps your base dom tree allows you to move a node programmatically. I am not familiar with xamarin)