Xamarin.Forms Android的自定义渲染器(Entry)中的OnElementChanged只被调用一次



我认为OnElementChanged应该被调用两次:一次是在创建控件时,一次是当处理控件时。这适用于我的iOS自定义渲染器,但不适用于Android自定义渲染器。

在iOS中,当一个页面被删除时,e.NewElement是控件,e.OldElement为null。当显示下一页时,上一个控件似乎已被处理,因为e.NewElement为null,而e.OldElement就是该控件。为新页面中的新控件调用OnElementChanged。安卓系统并非如此。

在Android中,每次显示带有控件的新屏幕时,都会调用OnElementChanged,其中e.OldElement为null,e.NewElement为控件(如预期(。但是,当显示更改为新屏幕时,不会为e.NewElement为null的以前控件调用OnElementChanged方法。相反,会调用新页面上新控件的OnElementChanged方法。

这个问题为什么会在安卓系统中出现?为什么会发生这种情况?

我的目的是在该控件被处理后安全地取消挂起该事件。

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;
}
}
...
}
}

安卓:

[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;                    
}
}
...
}
}

在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

最新更新