Android PopupWindow 中のボタン設置方法 

#はじめに
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」

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

```android: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のものではないので、
当然、関連を付けようとするとエラーが出ます。

正しい書き方は

```android: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です。