开发者

Perform UI updates in a loop

开发者 https://www.devze.com 2023-02-19 22:51 出处:网络
I am working on a mobile application UI that has a panel with momentum (for smooth scrolling) and I am currently updating the UI durring the smooth scrolling by using the following code:

I am working on a mobile application UI that has a panel with momentum (for smooth scrolling) and I am currently updating the UI durring the smooth scrolling by using the following code:

private void scrollKinetic()
{
    while (_curState == States.KineticScroll)
    {
        //  This gets how far the panel will move with the current velocity, then updates the velocity according to the current friction.
        var distY = GetDistance(scrVelocity.Y);
        var distX = GetDistance(scrVelocity.X);

        if (distY + distX <= 0)  //  Friction will eventually make distX and distY both 0
        {
            _curState = States.Idle;
            Invalidate();
            break;
        }

        //  CalculatePosition will move the panel accordingly.

        CalculatePosition(distY, scrVelocity.Y, false);
        CalculatePosition(distX, scrVelocity.X, true);

        Invalidate();
        friction++;
        Application.DoEvents();
 开发者_如何学Python   }
}

As you can see, Application.DoEvents(); is rearing its ugly head! I want to get rid of it, but I can't think of any way to loop and update the UI. Any help/ideas would be excellent!

I'm doing this on the .net CF, but I think it's a design issue, so I don't think the platform will matter too much.


I'd create a timer that would act like a "game loop" -- execute x times per second.
I would also keep track of how much time elapsed since the last call so that you can calculate how much to move based on that time elapsed. For extra performance, the timer could be started and stopped only if there is motion.

Depending on what kind of timer you use, you may need to marshal your UI update calls back to the UI thread.


You could try and remove the loop (and all App.DoEvent calls), make a call to KineticScroll in your OnPaint() method, and then call Invalidate() in your KineticScroll method.

I see that you have some kind of state tracking, so you can say something like:

if(_curState == States.KineticScroll)
    KineticScroll();

in your OnPaint() method, that way you only call it when your state is approprate.

Basically, your loop goes from a local while loop to: OnPaint -> KineticScroll -> Invalidate -> OnPaint...etc that way you get the same loop, w/o making a call to DoEvents!

0

精彩评论

暂无评论...
验证码 换一张
取 消