I have problem with my Android app. I've created custom view (http://syedwasihaider.github.io/blog/2015/07/12/XamarinViews/ up to step 2), overriden onDraw and I draw black screen and text "Draw {i}" where i
is number that increments every time onDraw occurs. I want to call this method 30 times/second (or 60), so I've set up timer that causes Invalidate() every 33 ms.
But Invalidate() doesn't cause onDraw at all! (It's not like its a delay between invalidate and ondraw, ondraw isn't called at all). I've tried to set SetWillNotDraw(false)
, but it didn't work. Here's my code:
class DrawCanvas : View
{
Context mContext;
public DrawCanvas(Context context) : base(context)
{
init(context);
}
public DrawCanvas(Context context, IAttributeSet attrs) : base(context, attrs)
{
init(context);
}
public DrawCanvas(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
init(context);
}
private void init(Context ctx)
{
mContext = ctx;
black = new Paint() { Color = Color.Black };
white = new Paint() { Color = Color.White };
Timer timer = new Timer(33);
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Invalidate();
}
int i = 0;
Paint black;
Paint white;
private void TestDraw(Canvas canvas)
{
canvas.DrawRect(0, 0, Width, Height, black);
canvas.DrawText("Draw " + i, 10, 10, white);
i++;
}
protected override void OnDraw(Canvas canvas)
{
TestDraw(canvas);
}
}
How can I either:
Call onDraw every 33ms
OR
Get canvas that is used in onDraw method? (tried to save canvas that comes as parameter in onDraw and use it later, but there was some weird behaviour, so it didn't work).
Call onDraw every 33ms
You could use Handler to implement this feature.
Every time your DrawCanvas
execute the OnDraw
method, you could send a message to Handler
, when you receive the message in Handler
, you could call the DrawCanvas
's Invalidate
method, this Invalidate
method will call OnDraw
method. It will keep going.
For example :
class DrawCanvas : View
{
MyHandler mHandler;
...
private void init(Context ctx)
{
mHandler = new MyHandler(this);
mContext = ctx;
black = new Paint() { Color = Color.Black,TextSize=56 };
white = new Paint() { Color = Color.White, TextSize = 56 };
}
...
protected override void OnDraw(Canvas canvas)
{
TestDraw(canvas);
mHandler.SendEmptyMessageDelayed(1,33);
}
...
public class MyHandler : Handler
{
private DrawCanvas drawCanvas;
public MyHandler(DrawCanvas drawCanvas)
{
this.drawCanvas = drawCanvas;
}
public override void HandleMessage(Message msg)
{
base.HandleMessage(msg);
drawCanvas.Invalidate();
}
}
}
Effect :
来源:https://stackoverflow.com/questions/46466427/invalidate-doesnt-cause-ondraw