[英]Flex AS3: ProgressBar doesn't move
我有些困惑,需要一些建議/幫助。
我有一個進度欄:
<mx:ProgressBar id="appProgress" mode="manual" width="300" label="{appProgressMsg}" minimum="0" maximum="100"/>
我有兩個偵聽器功能,一個設置進度,另一個設置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;
}
我想大量重復使用此進度條。 對於ProgressEvents,不一定,但在執行步驟時。
例如,我遍歷一堆數據庫插入,並想取消進度等。
這是一個示例:
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++;
}
}
}
}
一切正常。
也就是說,調用了偵聽器函數,並且我得到了如下的跟蹤輸出:
updateDatabase called.
Setting step:Updating project
Setting Perc 25
Setting Perc 50
Setting Perc 75
Setting Perc 100
問題是,僅顯示了最后一個百分比和步驟。 也就是說,完成所有操作后,進度條將跳至100%並顯示最后一步標簽。
有人知道為什么是這樣嗎?
預先感謝您的幫助,傑森
新的代碼效果非常好,我可能會添加:
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是單線程的。 在函數返回之前,顯示不會更新。 因此,您的代碼運行時間不得超過100毫秒(1/10秒),否則UI(甚至整個瀏覽器)將被鎖定。
通用解決方案是將您的工作分成多個幀,這是一些偽代碼:
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
您的偽代碼可用於更新進度條,但是在我的情況下,我的“工作”是將文件從DVD復制到appStorageDirectory,這似乎重新引發了您解決的問題—進度條現在不更新
這是我對您的解決方案的看法
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.