Invalidate doesn't cause OnDraw

僤鯓⒐⒋嵵緔 提交于 2019-12-12 10:15:33

问题


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).


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!