TL;DR
: Убегай, не идти по этому пути ...
На iOS
все, что отображает содержимое на экране происходит в UIView
(или подкласса) и drawRect:
является метод, который делает рисунок. Итак, когда drawRect: сделано, делается рисунок UIView
.
Примечание: Анимация может произойти, и вы можете увидеть завершенные сотни завершенных циклов рендеринга. Возможно, вам придется подключиться к каждому обработчику завершения анимации, чтобы определить, когда действительно делается «рендеринг».
Примечание: Розыгрыш производится за пределами экрана и в зависимости от чтения компакт-дисков, экран обновления Гц мог 30fps, или 60 FPS в случае IPad Pro это переменная (30-60hz) ...
Пример :
public class CustomRenderer : ButtonRenderer
{
public override void Draw(CGRect rect)
{
base.Draw(rect);
Console.WriteLine("A UIView is finished w/ drawRect: via msg/selector)");
}
}
на Android
общего способа привлечь контент через View
или подкласс, можно получить поверхность, рисовать/BILT через OpenGL на экран, и т.д. ... и что может не быть в пределах View
, но для y наш вариант использования, думаю View
s ..
View
s имеют Draw
методы, которые можно переопределить, и вы также можете подключить в ViewTreeObserver
и контролировать OnPreDraw
и OnDraw
, и т.д., и т.д., и т.д ... Иногда вы должны контролировать Родитель представления (ViewGroup
), чтобы определить, когда чертеж будет выполнен или когда он будет завершен.
Также все стандартные виджеты полностью завышены через ресурсы xml, и это оптимизировано, поэтому вы никогда не увидите вызов метода Draw/OnDraw (Примечание: вы всегда должны (?) Получать вызов слушателя OnPreDraw
, если вы его принудительно).
Различные View
s/s Widget
ведут себя по-разному, и там нет возможности рассмотреть все проблемы, вы будете иметь определения, когда View
действительно сделано «рендеринг» ...
Пример:
public class CustomButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer,
ViewTreeObserver.IOnDrawListener, ViewTreeObserver.IOnPreDrawListener
{
public bool OnPreDraw() // IOnPreDrawListener
{
System.Console.WriteLine("A View is *about* to be Drawn");
return true;
}
public void OnDraw() // IOnDrawListener
{
System.Console.WriteLine("A View is really *about* to be Drawn");
}
public override void Draw(Android.Graphics.Canvas canvas)
{
base.Draw(canvas);
System.Console.WriteLine("A View was Drawn");
}
protected override void Dispose(bool disposing)
{
Control?.ViewTreeObserver.RemoveOnDrawListener(this);
Control?.ViewTreeObserver.RemoveOnPreDrawListener(this);
base.Dispose(disposing);
}
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control?.SetWillNotDraw(false); // force the OnPreDraw to be called :-(
Control?.ViewTreeObserver.AddOnDrawListener(this); // API16+
Control?.ViewTreeObserver.AddOnPreDrawListener(this); // API16+
System.Console.WriteLine($"{Control?.ViewTreeObserver.IsAlive}");
}
}
}
Разное:
Примечание: Оптимизация макетов, кэширование контента, кэширование графического процессора, аппаратное ускорение, включенное в виджетах/представлении или нет, и т. Д. ... может помешать вызовам методов рисования ed ...
Примечание: Анимация, эффекты и т. д. могут привести к тому, что эти методы вызовут много, много, много раз, прежде чем область экрана будет полностью готова к отображению и готова к взаимодействию с пользователем.
Личные заметки: Я однажды спустился по этому пути из-за сумасшедших требований клиента, а после того, как я ударил головой по столу в течение некоторого времени, был сделан обзор фактической цели этой области пользовательского интерфейса, и я переписал требование и никогда не пробовал это снова ;-)
- Мне потребовалась минута, чтобы «щелкнуть», но щелкнуть мышью! Я в конечном итоге принимать ваши советы и работает быстро и тяжело от этого подхода. –