2009-01-16 16 views
11

यह निर्धारित करने का सबसे अच्छा तरीका क्या है कि उपयोगकर्ता की स्क्रीन पर फ्लेक्स/फ्लैश में कोई घटक दिख रहा है या नहीं? मैं जावा की Component.isShowing() विधि के लिए एक एनालॉग की तलाश में हूं।फ्लेक्स: निर्धारित करें कि कोई घटक

show और hide घटनाएं दृश्यता के लिए आग लगती हैं, और ऐसा लगता है कि व्यूस्टैक घटक के पहले वंशज के लिए काम करता है, लेकिन प्रदर्शन पेड़ को और नीचे नहीं।

उत्तर

5

UIComponent.visible एक वस्तु के बच्चों के लिए जरूरी नहीं है जहां दृश्यमान = झूठा। दस्तावेज़ों से:

"किसी भी मामले में ऑब्जेक्ट के बच्चे शो या छुपाएं ईवेंट नहीं छोड़ेंगे जब तक ऑब्जेक्ट ने ऐसा करने के लिए विशेष रूप से कार्यान्वयन नहीं लिखा हो।"

मैंने एक नमूना आवेदन लिखा जो यह सच साबित करता है। आप क्या कर सकते हैं एक अभिभावक पर झूठी होने के लिए दृश्य सूची जांच चलना है। असल में "दृश्यमान" झूठी सकारात्मक देता है लेकिन झूठी नकारात्मकता नहीं देनी चाहिए।

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

मैं इस पर तुच्छ परीक्षण की तुलना में अधिक कुछ नहीं किया है, लेकिन यह आपके लिए प्रारंभ करने चाहिए: यहाँ एक त्वरित उपयोगिता मैं एक साथ रखा है।

+0

वहाँ और आवेदन पर बंद करने के लिए किसी भी कारण है न केवल जब जनक == बातिल? –

+1

मुझे याद है कि एप्लिकेशन की "पैरेंट" संपत्ति एक ही उदाहरण पर एक सूचक हो सकती है जो अनंत लूप का कारण बनती है। मैं 100% निश्चित नहीं हूं और आसानी से पुष्टि नहीं कर सकता क्योंकि मैं अब कुछ वर्षों से कोई फ्लेक्स काम नहीं कर रहा हूं। –

1

ऐसा लगता है कि अजीब लगता है, अब मुझे विश्वास नहीं है कि यह निर्धारित करने के लिए एक सरल परीक्षण है कि घटक वास्तव में अर्थ में स्क्रीन पर दिखाई देता है घटक .isShowing() का तात्पर्य है।

यह भी सच है कि शो और छुपा घटनाएं डिफ़ॉल्ट रूप से बबल नहीं होती हैं, इसलिए यदि आप व्यूस्टैक कंटेनर के वंशज में दृश्यता परिवर्तनों के बारे में अधिसूचित होना चाहते हैं, तो आपको उन्हें स्पष्ट रूप से सुनना होगा। कार्यान्वयन विवरण व्यवहार किस तरह आप के बाद कर रहे थे के आधार पर भिन्न होगा, लेकिन सरल उदाहरण लेने के लिए:

<?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> 

... आप शो देख सकते हैं और प्रत्येक लेबल आग के लिए घटनाओं को छिपाने के एक बार उनके दिखाई गुण होगा उनके माता-पिता पैनलों से बंधे थे। उम्मीद है कि बिंदु को दर्शाता है; आप इसे बढ़ा सकते हैं हालांकि आपके आवेदन के लिए उपयुक्त है। सौभाग्य!

7

आप यह जांचना चाहते हैं कि घटक संपत्ति दृश्यमान सत्य है या यह डिस्प्लेलिस्ट में आपके घटक के सभी माता-पिता के लिए है, क्या मैं सही हूं?

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

यह मेरे कोड में एक अच्छा सुधार की तरह दिखता है। बहुत आसान अच्छा लगा। –

+0

'स्थैतिक प्रकार flash.display के साथ एक मान का लागू बल: संभवतः असंबद्ध प्रकार mx.core: DisplayObjectContainer। UIComponent.'। आपको 'प्रदर्शन' को 'DisplayObjectContainer' के रूप में घोषित करना चाहिए। –

11

... या परहेज प्रत्यावर्तन:

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

यदि आप पॉपअप का उपयोग करते हैं, तो फ्लेक्स उन्हें एप्लिकेशन की तुलना में एक अलग डिस्प्ले सूची में बनाता है, इसलिए अभिभावक सूची में Application.application के लिए परीक्षण काम नहीं करेगा। इसके बजाय चरण का उपयोग किया जाना चाहिए और सभी मामलों में काम करेगा। – Chris

0

मैं एक पुन: प्रयोज्य ढंग से एक ही प्राप्त करने के लिए कोशिश कर रहा था .. मैं लगभग बाहर एक तरह से getObjectsUnderPoint() का उपयोग कर पाया - इस वस्तु के तहत रिटर्न एक कण बिंदु, जेड-ऑर्डर (भले ही वे भाई बहन नहीं हैं, उदाहरण के लिए व्यूस्टैक, पॉपअप, ईसीसी।)।

असल में, मुझे मंच के किसी विशेष बिंदु के नीचे शीर्षतम प्रदर्शन वस्तु मिलती है, फिर परीक्षण ऑब्जेक्ट को खोजने के लिए प्रदर्शन ऑब्जेक्ट पदानुक्रम को ऊपर उठाएं। यदि मुझे लगता है, तो वस्तु दिखाई दे रही है (पदानुक्रम में दिखाई देने वाली वस्तुओं को getObjectsUnderPoint कॉल द्वारा पहले ही फ़िल्टर नहीं किया जाना चाहिए)।

समस्या यह है कि आपको अपने ऑब्जेक्ट के एक गैर-पारदर्शी बिंदु का उपयोग करना होगा (मेरे मामले में, मैंने राउंडर सीमाओं के कारण 5 पिक्सेल की ऑफसेट का उपयोग किया था), अन्यथा इसे इस फ़ंक्शन द्वारा नहीं उठाया जाएगा।

इसे सुधारने के लिए कोई विचार?

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

यदि कोई शीर्ष बाएं कोने किसी अन्य घटक द्वारा कवर किया गया है तो क्या यह एक घटक को अदृश्य के रूप में नहीं पहचान पाएगा? –

+1

stage.getObjectsUnderPoint को सभी डिस्प्ले ऑब्जेक्ट्स की एक सरणी वापस करनी चाहिए जिसमें उस स्थिति में "ब्लिटेड" पॉइंट हो, भले ही अन्य डिस्प्ले ऑब्जेक्ट्स द्वारा कवर किया गया हो (यही कारण है कि एक ऑब्जेक्ट के बजाय सरणी लौटा दी जाती है)। –

संबंधित मुद्दे