OnElementChanged в настраиваемом средстве визуализации (Entry) для Xamarin.Forms Android вызывается только один раз - PullRequest
1 голос
/ 09 июля 2020

Я считаю, что OnElementChanged должен вызываться дважды: один раз при создании элемента управления и один раз при его удалении. Это работает, как ожидалось, для моего iOS настраиваемого средства визуализации, но не для Android настраиваемого средства визуализации.

В iOS при отображении страницы e.NewElement является элементом управления, а e.OldElement имеет значение null. Когда отображается следующая страница, этот предыдущий элемент управления кажется удаленным, поскольку e.NewElement имеет значение null, а e.OldElement является этим элементом управления. OnElementChanged вызывается для новых элементов управления на новой странице. Это не относится к Android.

В Android каждый раз, когда отображается новый экран с элементами управления, OnElementChanged вызывается с e.OldElement как null и e.NewElement как элементом управления (как ожидается). Однако, когда отображение изменяется на новый экран, метод OnElementChanged не вызывается для предыдущих элементов управления с e.NewElement как null. Вместо этого вызываются методы OnElementChanged для новых элементов управления на новой странице.

Есть ли причина, по которой эта проблема возникает именно в Android? Есть ли какие-либо причины, по которым это могло происходить?

Моя цель - безопасно отключить событие после того, как этот элемент управления будет удален.

iOS:

[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace iOS.Renderers
{
    public class MyEntryRenderer: EntryRenderer
    {
        private UIButton _myButton = null;

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            // update control UI
            ...

            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe
                _myButton .TouchUpInside -= OnClearButtonTouched;
            }
            if (e.NewElement != null)
            {
                if (_myButton == null)
                {
                    // create button
                    _myButton = ...;
                }

                // Subscribe
                _myButton.TouchUpInside += OnClearButtonTouched;
            }
        }

        ...

    }
}

Android:

[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace Android.Renderers
{
    public class MyEntryRenderer: EntryRenderer
    {
        private FormsEditText _formsEditText;
        private Drawable _leftDrawable = null;

        public MyEntryRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            // update control UI
            ...

            base.OnElementChanged(e);

            // set appropriate event handler for when text is cleared

            if (_leftDrawable == null) {
                // get appropriate search drawable
                _leftDrawable = ...;
            }

            if (e.OldElement != null)
            {
                // Unsubscribe
                Control.AfterTextChanged -= AfterEntryTextChanged;
            }
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    _formsEditText = new FormsEditText(Context);
                    SetNativeControl(_formsEditText);
                }

                // Subscribe
                Control.AfterTextChanged += AfterEntryTextChanged;                    
            }
        }

        ...

    }
}

1 Ответ

3 голосов
/ 10 июля 2020

On Android отключает событие в Dispose:

bool _disposed;

protected override void Dispose(bool disposing)
{
    if (_disposed)
        return;

    _disposed = true;

    if (Control != null && disposing)
    {
        _myButton.TouchUpInside -= OnClearButtonTouched;
    }

    base.Dispose(disposing);
}  

См. Также EntryRenderer и [Android] Эффекты не отсоединяются и OnElementchanged (null) никогда не называется # 2520

...