仕事辞めたいおっさんの英雄譚

ものすごい勢いで仕事やめたいおっさんが、仕事を辞めるのをものすごく躊躇するブログ

Android でポップアップ(popupwindow)表示

ポップアップを試したところエラーが発生。

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

Unable to add window -- token null is not valid; is your activity running?

android - PopupWindow $BadTokenException: Unable to add window -- token null is not valid - Stack Overflow

よくわからんから調べてみると、ポップアップさせようとするタイミングが早過ぎるらしい。ActivityクラスのonCreateイベントの中ではライフサイクル上?早すぎる。 ので解決策は 別スレッドで処理をする必要があるらしく、それが Hundler?クラスってのを使う。
ここはまた調べていかないと。。

以下、エラーが出たコード。

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mPopupWindow = new PopupWindow(MainActivity.this);

        //レイアウト設定
        View popupView = getLayoutInflater().inflate(R.layout.popup_layout,null);
        Button btn = (Button)popupView.findViewById(R.id.close_button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(mPopupWindow.isShowing()){
                    mPopupWindow.dismiss();
                }

            }
        });

        try {
            mPopupWindow.setContentView(popupView);
            //背景設定
            mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.popup_background));

            // タップ時に他のViewでキャッチされないための設定
            mPopupWindow.setOutsideTouchable(true);
            mPopupWindow.setFocusable(true);

            // 表示サイズの設定
            float width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, getResources().getDisplayMetrics());

            mPopupWindow.setWindowLayoutMode((int) width, WindowManager.LayoutParams.WRAP_CONTENT);
            mPopupWindow.setWidth((int) width);
            mPopupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
            mPopupWindow.showAtLocation(findViewById(R.id.close_button), Gravity.CENTER, 0, 0);

onCreateの中でポップアップさせるとエラーが出てたので、ボタンを押下して
ポップアップさせる処理に帰ると上手く動いた。

もうひとつ気がついたこととして、このポップアップを使っているサンプルを見ると、
2つのタイプがある。Activityを継承したクラスと、Viewクラスを継承したクラス。
参考にしてたのは後者で、自分はActivity継承クラスで実装していたので、
エラーが出た。ライフサイクル関連が絡んでくるらしい。 ここらへんの差がもう一つわかってないので勉強が必要。後、別スレッドでの処理ってやつも。

備忘:

Android - PopupWindowで画面内にダイアログ風の表示をする方法 - Qiita

Y.A.M の 雑記帳: Android コードから PopupWindow を生成するときは setBackgroundDrawable() したほうがいいよ

[Android] DialogFragmentを使ってダイアログを表示する - Qiita