Fragment内のサイズが取得できない時の対応をしたら無限ループにはまった話

Android の Fragment 内にある View の中にある画像をレイアウトのサイズによって変更しようと思ったのですが…

onStart だとサイズ取得しても 0になる…。

        LinearLayout la= ( LinearLayout) v.findViewById(R.id.imageViewLinear);
        ViewGroup.LayoutParams lp = la.getLayoutParams();
        lp.height = la.getWidth() * 18 / 24;
        la.setLayoutParams(lp);

というわけで、

androidでレンダリング後のViewのサイズを取得する - @blog.justoneplanet.info
Fragment内のViewのwidthがなぜか0のときの対応方法 - リア充爆発日記

こちらのコードを拝借してみたところ

        v = inflater.inflate(R.layout.fragment_main, container, false);
        ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new    ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                    setupView();
            }
        });

なんということでしょう。 setupViewが呼ばれると、もう一度 onGlobalLayout が呼ばれて無限ループに!?

『OnGlobalLayoutListenerが引っかかり過ぎやしないかと思ったけど、アプリ起動→表示までの単純なフローでは2回しか呼ばれなかった。』って書いてあったけど、
どうやら、レイアウト変更する処理が入ると、まずいっぽい。

というわけで、OnStart の後で一回だけサイズ取得してレイアウト変更するように変更

        callGlobal = false;
        v = inflater.inflate(R.layout.fragment_main, container, false);
        ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new    ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if(!callGlobal) {
                    callGlobal = true;
                    setupImageView();
                }
            }
        });

これでいいらしい・ω・

Fragment内のサイズが取得できない時の対応をしたら無限ループにはまった話

Android の Fragment 内にある View の中にある画像をレイアウトのサイズによって変更しようと思ったのですが…

onStart だとサイズ取得しても 0になる…。

        LinearLayout la= ( LinearLayout) v.findViewById(R.id.imageViewLinear);
        ViewGroup.LayoutParams lp = la.getLayoutParams();
        lp.height = la.getWidth() * 18 / 24;
        la.setLayoutParams(lp);

というわけで、

androidでレンダリング後のViewのサイズを取得する - @blog.justoneplanet.info
Fragment内のViewのwidthがなぜか0のときの対応方法 - リア充爆発日記

こちらのコードを拝借してみたところ

        v = inflater.inflate(R.layout.fragment_main, container, false);
        ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new    ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                    setupView();
            }
        });

なんということでしょう。 setupViewが呼ばれると、もう一度 onGlobalLayout が呼ばれて無限ループに!?

『OnGlobalLayoutListenerが引っかかり過ぎやしないかと思ったけど、アプリ起動→表示までの単純なフローでは2回しか呼ばれなかった。』って書いてあったけど、
どうやら、レイアウト変更する処理が入ると、まずいっぽい。

というわけで、OnStart の後で一回だけサイズ取得してレイアウト変更するように変更

        callGlobal = false;
        v = inflater.inflate(R.layout.fragment_main, container, false);
        ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new    ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if(!callGlobal) {
                    callGlobal = true;
                    setupImageView();
                }
            }
        });

これでいいらしい・ω・

おすすめ

2件のフィードバック

  1. JD より:

    初めまして、上記内容コメントではないのですが、ご教示頂ければと思い書き込みしています。【Livedoor未加入のためメッセージ送信が出来ずです。】
    2012年08月14日
    Internet Explorer 6 Service Pack 1 サルベージしました
    の内容を拝見しました。あるマクロ動作のためIE6にダウンしなければならずIE8を削除しIE6インストールしようとしましたが出来ませんでした。何か得策をお持ちでしたらすみませんが連絡をお願い致します。

  2. 黒翼猫 より:

    環境もエラーも分からないのですが、うまくインストールできない場合は
    いったん実行ファイルのパッケージを解凍して、ie6setup.exe など
    手動で起動してみてください。
    できればコメントは関連のある記事につけていただけると助かります・ω・
    (昔の記事でも新着扱いになりますので)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です