Flex/Flash のコンポーネントがユーザーの画面に表示されているかどうかを判断する最善の方法は何ですか? Java のComponent.isShowing()メソッドに類似したものを探しています。
showおよびhideイベントは可視性のために発生します。これは、ViewStack コンポーネントの最初の子孫に対しては機能するようですが、表示ツリーのそれより下では機能しません。
Flex/Flash のコンポーネントがユーザーの画面に表示されているかどうかを判断する最善の方法は何ですか? Java のComponent.isShowing()メソッドに類似したものを探しています。
showおよびhideイベントは可視性のために発生します。これは、ViewStack コンポーネントの最初の子孫に対しては機能するようですが、表示ツリーのそれより下では機能しません。
...または再帰の回避:
public static function isVisible(obj:DisplayObject):Boolean
{
while (obj && obj.visible && obj !== Application.application)
{
obj = obj.parent;
}
return obj && obj.visible;
}
表示されているコンポーネントプロパティがtrueであり、これがDisplayList内のコンポーネントのすべての親に当てはまるかどうかを確認したいのですが、正しいですか?
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);
}
UIComponent.visible は、visible=false のオブジェクトの子に対して必ずしも有効ではありません。ドキュメントから:
「どちらの場合も、オブジェクトが実装を具体的に記述していない限り、オブジェクトの子は show または hide イベントを発行しません。」
これが正しいことを確認するサンプル アプリケーションを作成しました。あなたができることは、表示リストを調べて、親で false であることを確認することです。基本的に「可視」は誤検知を与えますが、誤検知を与えるべきではありません。ここに私がまとめた簡単なユーティリティがあります:
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;
}
}
}
これについては簡単なテストしか行っていませんが、これで始められるはずです。
奇妙に思えますが、Component.isShowing() が意味する意味で、コンポーネントが実際に画面上に表示されているかどうかを判断する簡単なテストがあるとは思えません。
また、show イベントと hide イベントはデフォルトではバブリングしないことも事実であるため、ViewStack コンテナの子孫の可視性の変更について通知を受けたい場合は、それらを明示的にリッスンする必要があります。実装の詳細は、その後の動作の種類によって異なりますが、簡単な例を挙げると:
<?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>
...表示されているプロパティが親パネルにバインドされると、各ラベルの表示イベントと非表示イベントが発生することがわかります。うまくいけば、それは要点を示しています。アプリケーションに最適な方法で拡張できます。幸運を!
私は再利用可能な方法で同じものを取得しようとしていました.. getObjectsUnderPoint() を使用する方法をほとんど見つけました - これは特定のポイントの下にあるオブジェクトを z オーダーで返します (ViewStack、Popups、ecc などの兄弟でなくても)。 .)。
基本的に、ステージの特定のポイントの下にある最上位の表示オブジェクトを取得してから、表示オブジェクトの階層を上ってテスト対象のオブジェクトを見つけます。見つかった場合、オブジェクトは表示されます (階層内の非表示オブジェクトは、getObjectsUnderPoint 呼び出しによって既に除外されているはずです)。
ここでの問題は、オブジェクトの不透明な点を使用する必要があることです (私の場合、境界線が丸くなるために 5 ピクセルのオフセットを使用しました)。そうしないと、この関数によって検出されません。
それを改善するためのアイデアはありますか?
コスマ
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;
}