简体   繁体   English

Flex AS3:ProgressBar不会移动

[英]Flex AS3: ProgressBar doesn't move

I am a little stuck and need some advice/help. 我有些困惑,需要一些建议/帮助。

I have a progress bar: 我有一个进度栏:

<mx:ProgressBar id="appProgress" mode="manual" width="300" label="{appProgressMsg}" minimum="0" maximum="100"/>

I have two listener functions, one sets the progress, and one sets the appProgressMsg: 我有两个侦听器功能,一个设置进度,另一个设置appProgressMsg:

public function incProgress(e:TEvent):void {
    var p:uint = Math.floor(e.data.number / e.data.total * 100);
    trace("Setting Perc." + p);
    appProgress.setProgress(p, 100);
}
public function setApplicationProgressStep(e:TEvent):void {
    trace("Setting step:" + e.data);
    appProgressMsg = e.data;
}

I want to reuse this progress bar alot. 我想大量重复使用此进度条。 And not necessarily for ProgressEvents, but when going through steps. 对于ProgressEvents,不一定,但在执行步骤时。

For instance, I loop over a bunch of database inserts, and want to undate the progress etc. 例如,我遍历一堆数据库插入,并想取消进度等。

Here is a sample: 这是一个示例:

public function updateDatabase(result:Object):void {
    var total:int = 0;
    var i:int = 0;
    var r:SQLResult;
    trace("updateDatabase called.");
    for each (var table:XML in this.queries.elements("table")) {
        var key:String = table.attribute("name");
        if (result[key]) {
            send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
            i = 1;
            total = result[key].length;
            for each (var row:Object in result[key]) {
                //now, we need to see if we already have this record.
                send(TEvent.UpdateApplicationProgress, { number:i, total: total } );
                r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
                if (r.data == null) {
                    //there is no entry with this id, make one.
                    this.query(table.insert, row);
                } else {
                    //it exists, so let's update.
                    this.update(key, row);
                }
                i++;
            }
        }

    }
}

Everything works fine. 一切正常。

That is, the listener functions are called and I get trace output like: 也就是说,调用了侦听器函数,并且我得到了如下的跟踪输出:

updateDatabase called.
Setting step:Updating project
Setting Perc 25
Setting Perc 50
Setting Perc 75
Setting Perc 100

The issue is, only the very last percent and step is shown. 问题是,仅显示了最后一个百分比和步骤。 that is, when it's all done, the progress bar jumps to 100% and shows the last step label. 也就是说,完成所有操作后,进度条将跳至100%并显示最后一步标签。

Does anyone know why this is? 有人知道为什么是这样吗?

Thanks in advance for any help, Jason 预先感谢您的帮助,杰森

The new code, which works awesomely I might add: 新的代码效果非常好,我可能会添加:

public function updateDatabase(result:Object, eindex:int = 0, sindex:int = 0 ):void {
    var total:int = 0;
    var i:int = 0;
    var j:int;
    var r:SQLResult;
    var table:XML;
    var key:String;
    var elems:XMLList = this.queries.elements("table");
    var startTime:int = getTimer();
    var row:Object;
    for (i = eindex; i < elems.length(); i++) {
        table = elems[i];
        key = table.attribute("name");
        if (!result[key])
            continue;
        total = result[key].length;
        send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
        for (j = sindex; j < result[key].length; j++) {
            if (getTimer() - startTime > 100) {
                setTimeout(updateDatabase, 100, result, i, j);
                send(TEvent.UpdateApplicationProgress, { number:j, total: total } );
                return;
            }
            row = result[key][j];
            r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
            if (r.data == null) {
                //there is no entry with this id, make one.
                this.query(table.insert, row,false);
            } else {
                //it exists, so let's update.
                this.update(key, row,false);
            }
        }
        send(TEvent.UpdateApplicationProgress, { number:1, total: 1 } );
    }
}

Flash is single threaded. Flash是单线程的。 The display will not update until your function returns. 在函数返回之前,显示不会更新。 For this reason, you should never have any code that runs for longer than about 100ms (1/10th of a second), otherwise the UI (or even the entire browser) will appear to be locked up. 因此,您的代码运行时间不得超过100毫秒(1/10秒),否则UI(甚至整个浏览器)将被锁定。

The general solution is to split up your work over multiple frames, here is some pseudo-code: 通用解决方案是将您的工作分成多个帧,这是一些伪代码:

function doWork(arg1:Obj, arg2:Obj, start:int=0) {
   var startTime = getTimer(); // store starting time
   for(i=start; i<length; i++) {
     if(getTimer() - startTime > 100) { // see if we've been working too long
        trace("Current progress: "+(i/length * 100)+"%");
        updateProgress( i / length );
        setTimeout(doWork, 100, arg1, arg2, i); // schedule more work to be done
        return; // stop current loop
     }
     trace("Working on item "+i);
     // processing here
   }
   trace("All work done");
}

doWork(data1, data2); // start the work

Your pseudo-code works for updating the progress bar however in my case my "work" was copying of files from DVD to the appStorageDirectory which seem to reintroduce the same issue that your work around resolved - the progress bar now does not update 您的伪代码可用于更新进度条,但是在我的情况下,我的“工作”是将文件从DVD复制到appStorageDirectory,这似乎重新引发了您解决的问题—进度条现在不更新

Here is my hack of your solution 这是我对您的解决方案的看法

function doWork(arg1:int, arg2:int, start:int=0) {
    var startTime = getTimer(); // store starting time
    for(var i:int=start; i<arg2; i++) {
        if(getTimer() - startTime > 100 ) { // see if we've been working too long
          trace("Current progress: "+(i/arg2 * 100)+"%");
          setTimeout(doWork, 100, i, arg2, i); // schedule more work to be done
          return; // stop current loop
      }
      trace("Working on item "+i);
      dispatchEvent(new progressMadeEvent("incrementChange",i,arg2))
      var dir:String = copyRes[i].nativePath.toString().split(OSSep).pop()
    copyRes[i].copyTo(appStore.resolvePath(dir)) // copies dir from DVD to appStorageDir
    }
    trace("All work done");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM