2010-01-22 21 views
9

Yeniden boyutlandırma olayımda küçük bir sorun yaşıyorum ... Kendim bir bileşen oluşturdum ve her yeniden boyutlandırma etkinliğinde bu bileşen karmaşık bir yöntem çalıştırıyor. Sorun şu: Penceremi büyütürken veya geri yüklediğimde, gerçek bir kısa süre içinde bu olaya birkaç kez denir, yöntemimin başka bir tane başlamadan önce tamamen çalıştırılmasına yetecek kadar zaman kalmaz ... Bilmek isterim eğer her neyse, her bir yeniden boyutlandırma hareketinin sonunda bu yöntemi çalıştır. TeşekkürlerFlex - ResizeEvent.RESIZE ile sorun

cevap

20

Yeniden boyutlandırma sırasında tüm kareleri tetikleyen bir ResizeEvent'e (örneğin, en üst düzeye çıkarsanız ve bileşenin widh/ehight = 0 - width/height = MaxValue öğesinden yeniden çizilmesi için 3 karesi alırsa) tepki vermek yerine, Yeniden boyutlandırma olayı üç kez ateşlenir, genişlik ve yükseklik özelliklerini 'izleyebilir'.

var widthWatch:ChangeWatcher = ChangeWatcher.watch(this, 'widht', resizeHandler) 
var heightWatch:ChangeWatcher = ChangeWatcher.watch(this, 'height' resizeHandler) 

bu irade, aslında, bağlama verilere benzer özelliklere izlemek ve resizeHandler zaman genişlik veya yükseklik değişikliği yürütün. Bu, genişlik ve yükseklik aynı zamanda değişirse, işleyicinizi iki kez ateşlemek gibi hafif bir dezavantaja sahiptir, ancak işin yapılması için programlanmadığı takdirde işleyiciler tarafından çalıştırılan üçüncü bir işlevle çözülebilir. . Kod: genişlik ve yükseklik özellikleri değişmiştir sonra genişlik ve yükseklik özellikleri correclty güncellenir önce yeniden boyutlandırma olay wich yangınları aksine ateşler çünkü

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete(event)"> 
<mx:Script> 
<![CDATA[ 
    import mx.binding.utils.ChangeWatcher; 

    private var widthWatch:ChangeWatcher; 
    private var heightWatch:ChangeWatcher; 
    private var resizeExecuting:Boolean = false; 

    private function onCreationComplete(event:Event):void 
    { 
    widthWatch = ChangeWatcher.watch(this,'width',onSizeChange); 
    heightWatch = ChangeWatcher.watch(this,'height',onSizeChange); 
    } 

    private function onSizeChange(event:Event):void 
    { 
    if(!resizeExecuting) 
    callLater(handleResize); 
    resizeExecuting = true; 
    } 

    private function handleResize():void 
    { 
    //do expensive work here 
    resizeExecuting = false; 
    } 

    private function stopWatching() 
    { 
    //invoke this to stop watching the properties and prevent the handleResize method from executing 
    widthWatch.unwatch(); 
    heightWatch.unwatch(); 
    } 

]]> 
</mx:Script> 
</mx:Application> 

Ben değişim gözlemcisi yöntemini tercih etmektedir.

+0

bu gerçekten harika bir şey, bunu paylaştığınız için teşekkürler! Bu soruna bir ek olarak – D3vtr0n

+1

, Dedoose'daki grafik bileşenlerimiz için çok fazla sorun yaşarken, karmaşık operasyonunuzu greenthreading ile parçalara ayırıyoruz (http://code.google.com/p/greenthreads/). Geçerli GreenThread'inizde bir tutaç tutun ve eğer tamamlanmadıysa, yeniden başlatmak için orta hesaplamayı durdurabilirsiniz. Bu, bazı büyük UI yanıt verebilirliği ve aynı zamanda yeniden boyutlandırmada karmaşık hesaplamalar ile ilgilenir. – JTtheGeek

+0

Bu gerçekten yararlı oldu, teşekkürler. – ggkmath

3

Yeniden boyutlandırma olaylarını tek bir olayda birleştirmek istersiniz. David Coletta, this presentation'daki etkinlik birleştirme hakkında kısaca konuştu, ama nasıl yaptığını anlatıp hatırlamadığını hatırlamıyorum. Eğer olay işleyicisi içinde bir şey yapıyoruz gibi bana geliyor

resizeHandler(resizeEvent): 
    if (resizeEventReceived) 
     return 
    resizeEventReceived = true 
    Timer.startIn(30 /*ms*/).withHandler(doResize) 

doResize(timerEvent): 
    /* do actual resize processing */ 
    resizeEventReceived = false 
1

o neden olan:

Sen Aşağıdaki sözde kod düzeni edeceğiz bunlardan biri, bir dizi yolla bu yapabileceğini Yeni bir ResizeEvent.RESIZE tetiklenecek. ActionScript tek bir iş parçacığı içinde çalıştığı için, işleyiciniz çalışırken bir şekilde tetiklemediğiniz sürece bağımsız bir kaynak bu olayı gönderebilir.

1

Ben esnek size yardımcı olabilecek tam Bileşen yaşam döngüsünü sahip olduğunu işaret etmek istiyorum:

bu deneyin:

  1. doğrudan ekran değişiklikleri hesaplamak, ama updateDisplayList yönteminde bunu yapmayın .
  2. ResizeEvent alırken, yalnızca Burada Flex3 Bileşen yaşam döngüsü hakkında daha fazla bilgi bulabilirsiniz

updateDisplayList() yürütülmesini tetikleyecek bir çerçeve bayrağı ayarlar invalidateDisplayList() yöntemini çağırır: http://www.dlgsoftware.com/primers/Primer_on_Flex3_Component_Lifecycle.htm