« 豊かな生活 | ホーム | 業務日誌0827 »
2005年8月25日
scrollPaneのrefreshPane()
今開発している(我が家ではデスマーチプロジェクトと呼んでいる)案件で、当初の制作で僕は、 デザインの変更がやりやすいからという理由でFlashのV1コンポーネントを使用して開発を行ってた。
ところが、仕様書にはV2コンポーネントで作ることになっていたのもあり、 結局途中でV2コンポーネントに差し替える必要性が出てきた。
何週間か前に一度チャレンジして挫折した。
どういう訳か、無限ループに陥ってしまってにっちもさっちも行かなくなってしまったのだ。あーあ。
V2コンポーネントは、デザインの変更がやりにくい(スキンと呼ばれるものを新たに定義して、
クラスをいじったりなんたらかんたらしないといけない)以外は非常に高機能で、ユーザビリティ、
アクセシビリティについてもよく考えられて作られている。
また、5種類以上のコンポーネントを用いた場合に、ファイルサイズが最適になるように設計されているらしい。
こんなうんちくはどうでもいいのだが、結局なんとしてでもV2コンポーネントに差し替えしなければならなくなった。あーあ。
V1コンポーネントとV2コンポーネントは原則、同じムービーに存在していてはいけない。動作はするのだけど、推奨はされないのだ。
しかたなく、V1コンポーネント達のプロパティを紙に書き留め、ステージから削除して、ライブラリから削除して、
新たにV2コンポーネントを配置していった。
んで、ターゲットとなるムービークリップのidを指定して、パブリッシュする。
案の定、無限ループ。
無限ループが起きるなんて、たいていはfor文の条件の記述が間違っているとかなんだけど、
コンポーネントが変わったからと言ってその条件が変わるとも思えない。ならば、相対参照させているパスの記述かなぁ…
とトイレで少し思いついて、気になる部分にブレークポイントを設定。
1行ずつステップインさせてみる。
そしたら、なんなくfor文を指定回数分処理して抜けた。え?これじゃ無限ループになんてならないよ。
僕はそのまま再生ボタンをクリックして、様子を伺うことにした。
そしたら、またデバッガがさっきのブレークポイントを指している。
処理が終わったはずなのに、また処理をしようとしている。犯人はやはりこのあたりに潜んでいた。
その関数の一番最後に記されてあった、refreshPane();である。
V1コンポーネントでrefreshPane()すると、ScrollPaneのコンテンツの大きさを再度チェックして、
スクロールバーを更新する。
ところが、V2コンポーネントではコンテンツをリロードするようになっている。
つまり、スクロールバーを更新するつもりで入れてあったrefreshPane()がコンテンツリロードにそのまま使われてしまって、 リロードされたコンテンツが再度処理を行ってrefreshPane()…とループになってしまっていた。
さっそくリサーチの旅に出た。
ついでにmixiで吠えたら、うえきさんとサブリンさんがナイスなソリューションを提供してくれた。
ScrollPane.invalidate();//うえきさん案
ScrollPane.onComplete();//サブリンさん案
onCompleteは最終的にinvalidateするので、結果としては同じ動作になる。
テストムービーではどちらでもスクロールバーを更新できたのだが、本番用にセットすると、更新のタイミングがコンテンツの更新とずれるのか、
うまく動作しなかった。
僕がネットで見つけてきた方法は、setSize()を使う方法。
ScrollPane.setSize(ScrollPane.__width,ScrollPane.__height,false);
みたいに、
ScrollPaneのクラスであるsetSizeに引数として自分の幅と高さ(ただしここではプロパティの_widthなどではなく、
コンポーネント内で定義されているスクロールバーの値を加味したプロパティである__width←アンダーバー2個 をとってくる必要がある)
を与えてあげることでうまくいった。
呼び出しする階層はいろいろあるだろうから、適当に_parentするなりして調整してくれ。
まぁ、とにかく、お二方の助言もあってなんとかV2コンポーネントへの差し替えが実現しそうである。めでたしめでたし。
トラックバック(0)
トラックバックURL: http://okamot.com/mt/hage-tb.cgi/903
はじめまして。
私は今ActionScript2.0で開発を行っていて、
scrollPaneのスクロールバー再描画の問題でここ数日悩みっきりでしたが…
ScrollPane.setSize(ScrollPane.__width,ScrollPane.__height,false);
この1行で全てが解決しました…!
本当にありがとうございます○┓