2009-01-16 17 views

Odpowiedz

5

UIComponent.visible nie jest obowiązkowe dla dzieci obiektu, gdzie visible = false. Z dokumentacji:

"W obu przypadkach elementy potomne obiektu nie będą emitować zdarzenia pokazu lub ukrywania, o ile obiekt nie napisał specjalnie do tego celu."

Napisałem przykładową aplikację, która potwierdza, że ​​jest prawdą. Możesz przejść do listy wyświetlania, sprawdzając, czy widoczna jest wartość false dla rodzica. Zasadniczo "widoczny" daje fałszywe alarmy, ale nie powinien dawać fałszywych negatywów. Oto szybkie narzędzie ułożyła:

package 
{ 
    import flash.display.DisplayObject; 

    import mx.core.Application; 

    public class VisibilityUtils 
    { 
     public static function isDisplayObjectVisible(obj : DisplayObject) : Boolean { 
      if (!obj.visible) return false; 
      return checkDisplayObjectVisible(obj); 
     } 

     private static function checkDisplayObjectVisible(obj : DisplayObject) : Boolean { 
      if (!obj.parent.visible) return false; 
      if (obj.parent != null && !(obj.parent is Application)) 
       return checkDisplayObjectVisible(obj.parent); 
      else 
       return true; 
     } 
    } 
} 

nie robiłem nic więcej niż to na testach trywialne ale powinno Ci zacząć.

+0

Czy istnieje jakikolwiek powód, aby zatrzymać się na wniosku, a nie tylko wtedy, gdy rodzic == null? –

+1

Przypominam sobie, że właściwość "rodzica" aplikacji może być wskaźnikiem powrotu do tej samej instancji, która spowodowałaby nieskończoną pętlę. Nie jestem w 100% pewny i nie mogę tego łatwo potwierdzić, ponieważ od kilku lat nie pracuję z Flex. –

1

Dziwne, jak się wydaje, teraz, kiedy o tym wspomniałeś, nie wierzę, że istnieje prosty test, który pozwala określić, czy dany komponent jest rzeczywiście widoczny na ekranie w tym sensie, jak sugeruje to Component.isShowing().

To prawda, że ​​pokazywanie i ukrywanie wydarzeń nie jest domyślnie bańką, więc jeśli chcesz otrzymywać powiadomienia o zmianach widoczności u potomka kontenera ViewStack, musisz ich wyraźnie wysłuchać. Dane wdrożeniowe będą się różnić w zależności od rodzaju zachowań byłaś po, ale do podjęcia prosty przykład:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> 
    <mx:VBox> 
     <mx:HBox> 
      <mx:Button id="btn1" click="vs.selectedIndex = 0" label="Show 1" /> 
      <mx:Button id="btn2" click="vs.selectedIndex = 1" label="Show 2" /> 
     </mx:HBox> 
     <mx:ViewStack id="vs" selectedIndex="0"> 
      <mx:Panel id="panel1"> 
       <mx:Label id="label1" text="Label 1" show="trace('showing label 1')" hide="trace('hiding label 1')" visible="{panel1.visible}" /> 
      </mx:Panel> 
      <mx:Panel id="panel2"> 
       <mx:Label id="label2" text="Label 2" show="trace('showing label 2')" hide="trace('hiding label 2')" visible="{panel2.visible}" /> 
      </mx:Panel> 
     </mx:ViewStack> 
    </mx:VBox> 
</mx:Application> 

... zobaczysz pokaz i ukryć zdarzenia dla każdego pożaru etykiet po ich widzialne obiekty zostały powiązane z ich panelami macierzystymi ". Mam nadzieję, że ilustruje to punkt; możesz go przedłużyć, jednak najlepiej pasuje do Twojej aplikacji. Powodzenia!

7

Chcesz sprawdzić, czy widoczna właściwość komponentu ma wartość true, a dotyczy to wszystkich elementów macierzystych komponentu w liście wyświetlania, czy mam rację?

public static function isVisible(c : UIComponent) : Boolean { 
    if (c == null) return false; 
    if (c is Application) return c.visible; 
    return c.visible && isVisible(c.parent); 
} 
+0

To wygląda na poprawę mojego kodu. Znacznie prostsze. Miły. –

+0

'Niejawna wymuszona wartość ze statycznym typem flash.display: DisplayObjectContainer na prawdopodobnie niepowiązanym typie mx.core: UIComponent.". Powinieneś zadeklarować 'c' jako' DisplayObjectContainer'. –

11

... lub unikania rekurencji:

public static function isVisible(obj:DisplayObject):Boolean 
{ 
    while (obj && obj.visible && obj !== Application.application) 
    { 
     obj = obj.parent; 
    } 
    return obj && obj.visible; 
} 
+0

Jeśli używasz wyskakujących okienek, Flex tworzy je na innej liście wyświetlania niż aplikacja, więc testowanie aplikacji Application.application na liście nadrzędnej nie będzie działać. Etap powinien być użyty zamiast tego i będzie działał we wszystkich przypadkach. – Chris

0

starałem się uzyskać to samo w wielokrotnego użytku sposób .. I prawie dowiedział sposób używając getObjectsUnderPoint() - ta zwraca obiekt pod punkt particolar, z-uporządkowany (nawet jeśli nie są rodzeństwem, np. ViewStack, Popups, ecc.).

Zasadniczo pobieram najwyższy obiekt wyświetlany pod konkretnym punktem stołu montażowego, a następnie w górę od hierarchii obiektów wyświetlanych, aby znaleźć przetestowany obiekt. Jeśli go znajdę, obiekt jest widoczny (niewidoczne obiekty w hierarchii powinny być już odfiltrowane przez wywołanie getObjectsUnderPoint).

Problem polega na tym, że musisz użyć nieprzezroczystego punktu obiektu (w moim przypadku użyłem przesunięcia o 5 pikseli ze względu na zaokrąglone krawędzie), w przeciwnym razie nie zostanie ono odebrane przez tę funkcję.

Wszelkie pomysły na ulepszenie?

Cosma

public static function isVisible(object:DisplayObject):Boolean { 
    var point:Point = object.localToGlobal(new Point(5, 5)); 
    var objects:Array = object.stage.getObjectsUnderPoint(point); 
    if (objects.length > 0) { 
     if (isDescendantOf(object, objects[objects.length - 1] as DisplayObject)) { 
      return true; 
     } 
    } 
    return false; 
} 

public static function isDescendantOf(parent:DisplayObject, child:DisplayObject):Boolean { 
    while (child.parent != null) { 
     if (child.parent === parent) { 
      return true; 
     } else { 
      child = child.parent; 
     } 
    } 
    return false; 
} 
+0

Czy nie wykryłoby elementu jako niewidocznego, jeśli lewy górny róg jest pokryty innym komponentem ?. –

+1

stage.getObjectsUnderPoint powinien zwrócić tablicę wszystkich obiektów wyświetlanych, które mają punkt "blitting" w tej pozycji, nawet jeśli są pokryte przez inne obiekty wyświetlane (to jest powód, dla którego zwracana jest tablica zamiast pojedynczego obiektu). –

Powiązane problemy