1

勢いのあるパネル(スムーズなスクロール用)を備えたモバイルアプリケーションUIに取り組んでおり、現在、次のコードを使用してスムーズなスクロール中にUIを更新しています。

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();
    }
}

ご覧のとおりApplication.DoEvents();、醜い頭を育てています!それを取り除きたいのですが、UIをループして更新する方法が思いつきません。どんな助け/アイデアも素晴らしいでしょう!

私はこれを.netCFで行っていますが、これは設計上の問題だと思うので、プラットフォームはそれほど重要ではないと思います。

4

2 に答える 2

1

ループ(およびすべてのApp.DoEvent呼び出し)を削除し、OnPaint()メソッドでKineticScrollを呼び出してから、KineticScrollメソッドでInvalidate()を呼び出すことができます。

ある種の状態追跡があるので、次のように言うことができます。

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

OnPaint()メソッドでは、この方法では、状態が適切な場合にのみ呼び出すことができます。

基本的に、ループはローカルのwhileループから次OnPaint -> KineticScroll -> Invalidate -> OnPaint...etcのようになります。そうすれば、DoEventsを呼び出さなくても、同じループを取得できます。

于 2011-03-24T14:50:46.317 に答える
1

「ゲームループ」のように機能するタイマーを作成します。1秒間にx回実行します。
また、最後の呼び出しからの経過時間を追跡して、その経過時間に基づいて移動する量を計算できるようにします。パフォーマンスを向上させるために、動きがある場合にのみタイマーを開始および停止できます。

使用するタイマーの種類によっては、UI更新呼び出しをUIスレッドにマーシャリングする必要がある場合があります。

于 2011-03-24T04:17:44.253 に答える