LoginSignup
1
0

More than 5 years have passed since last update.

Android PopupWindow 中のボタン設置方法

Posted at

はじめに

androidの開発でpopupWindowの中にボタンを設置したときにあった問題の解決方法をまとめます。

  • 実現したい機能

    • popupされたwindowの中にボタンを設置
  • 利用したandoirdのclass

    • android.widget.PopupWindow
  • 問題点

    • popupされたwindowの中のボタンにOnClickListenerがうまく付かない

popupWindowの使い方

  • 必要なactivity
    • popup対象のwindowのactivity
    • popupWindowを表示するactivity
  • 必要なclass
    • popupWindowを表示するactivityのclass

つまり、classはpopupWindowを表示するactivityのもののみでいいので、popup対象となるwindowのほうは別activityでlayoutなどを構築して、あとclassでpopupWindowsの関連の関数を使ってactivityを呼び出せばいいです。

分かりやすくするために、以下と定義します。

  • popupWindowを表示するactivity
    • 「my_activity」
  • popup対象のwindowのactivity
    • 「window_activity」

コアのコードの部分は以下です。(前後の処理のコードは割愛)

mypopup.class
import android.widget.PopupWindow

…
(略)
…
Button showWindow = findViewById(R.id.show_button);
showWindow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
   // popupWindow用のviewを宣言し、window_activityと関連を付け
   View popView = SocialFragment_Topic.this.getLayoutInflater().inflate(R.layout.window_activity, null);

   // popupWindow関数を利用して初期化するときのlayoutパラメータを設定
   PopupWindow ppw = new PopupWindow(popView, LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); 

…
(略)
…

   // windowのpopup、showAtLocationは指定場所でpopupする関数
   // パラメータ
   // #1 : どのviewでwindowを作成する(popupする)
   // #2 : 相対位置(TOP,LEFT,RIGHT,BOTTOM)
   // #3 : X方向でのオフセット
   // #4 : Y方向でのオフセット
   ppw.showAtLocation(findViewById(R.id.window_anchor_linearLayout), Gravity.BOTTOM,0,0);
}

こういう感じでコードを書けば、「my_activity」中の「show」ボタンを押すと、popupWindow自体は実現できるはずです。

popupWindow中のボタン

一般的に下のコードのような感じでボタンのviewを宣言してOnClickListenerの中に詳しい処理を書けば、ボタンを押すと反応するはずです。

button myButton = findViewById(R.id.popupwindow_button);
myButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                    }
                });

popupされたwindowの中には、こういうふうに書いたらOnClickListenerはエラーで落ちます。

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

viewとの関連がつけてない!
ちゃんとこれをしたのに?
button myButton = findViewById(R.id.popupwindow_button);

問題はこの処理は「my_activity」に「window_activity」中のボタンと関連をつけようとするからです。
popupされたwindowの中のものは、表示するほうのactivityのものではないので、
当然、関連を付けようとするとエラーが出ます。

正しい書き方は

mypopup.class
import android.widget.PopupWindow

…
(略)
…
Button showWindow = findViewById(R.id.show_button);
showWindow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
   // popupWindow用のviewを宣言し、window_activityと関連を付け
   View popView = SocialFragment_Topic.this.getLayoutInflater().inflate(R.layout.window_activity, null);

   // popupWindow関数を利用して初期化するときのlayoutパラメータを設定
   PopupWindow ppw = new PopupWindow(popView, LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); 

…
(略)
…

   button myButton = popView.findViewById(R.id.popupwindow_button);
   myButton.setOnClickListener(new View.OnClickListener() {
                       @Override
                       public void onClick(View v) {
                      ...(何かの処理)..
                       }
                   });

…
(略)
…

   // windowのpopup、showAtLocationは指定場所でpopupする関数
   ppw.showAtLocation(findViewById(R.id.window_anchor_linearLayout), Gravity.BOTTOM,0,0);

}
…
(略)

誤:

button myButton = findViewById(R.id.popupwindow_button);

正:

button myButton = popView.findViewById(R.id.popupwindow_button);

popViewは

View popView = SocialFragment_Topic.this.getLayoutInflater().inflate(R.layout.window_activity, null);

で宣言したviewです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0