Met4licのあけくれ帖

日常とか、勉強したこととかいろいろ書いていくつもりのブログです

Androidでのつまづき01「ButtonのsetOnClickListener」

さてさて、すごい初歩的なところで躓いたので、メモとして残しておく。
xmlでレイアウトを作り、そこにidをつけてボタンを管理していた時のこと。
いくつかのボタンのクリックイベントの処理を追加するために、
setOnClickListener()を使って、idによってsetする処理を変えるために以下のようなコードを書いた。

@Override
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button aBtn = (Button)findViewById(R.id.aBtn);
        Button bBtn = (Button)findViewById(R.id.bBtn);
        Button cBtn = (Button)findViewById(R.id.cBtn);
        aBtn.setOnClickListener(this);
        bBtn.setOnClickListener(this);
        cBtn.setOnClickListener(this);
 }
 public void onClick(View v){
        if(v == (Button)findViewById(R.id.aBtn)){}
        else if(v == (Button)findViewById(R.id.bBtn)){}
        else{}
 }

まぁ、書き方が汚いのは置いといてください。
こうすると、どうやらエラーを吐かれるようで。。。
エラーが出ているのはsetOnClickListener(this)の部分。
エラーメッセージを見ると
「setOnClickListener(android.view.View.OnClickListener) in View
cannot be applied to (packagename.MainActivity)」と言われている。
「ButtonのsetOnClickListenerでthisが使えない?」と思ってしまった。
多くのサンプルコードを載せているサイトを見てみると、
この書き方でなんら問題は起こらないはずなのだが…
いろいろ調べていると、こちらに行き当たった↓
あかばね式 [Android] setOnClickListener ごときですっかりハマってしまい非常にうんざりしましたよ
この方も、自分と同じような症状で悩んでいたようで、解決策を提示してくれていました。
修正前:

aBtn.setOnClickListener(this);
bBtn.setOnClickListener(this);
cBtn.setOnClickListener(this);

これを
修正後

aBtn.setOnClickListener((View.OnClickListener)this);
bBtn.setOnClickListener((View.OnClickListener)this);
cBtn.setOnClickListener((View.OnClickListener)this);

こう変更したら通るようになりました。
つまり、thisを(View.OnClickListener)にキャストすれば使える、ということらしい。
多くのサイトが修正前を載せているのは、たぶんAndroidの機能変更か何かで変わったのだが
古い情報が残っている、ということなのかもしれない。

…インターネットの負の一面を垣間見た気がする。

setOnClickListener this エラーor使えないorできない
等で検索する人の助けになれば幸いです。


追記:@2015/11/26

そもそも原因がまったく違うところにあったことも判明しました。
自分で書いてたコードでActivityクラスを作った時に

public class MainActivity extends Activity{....}

としていたのですが、この状態でonClickをActivity内に作って、巷のサンプルコードの使い方、

aBtn.setOnClickListener(this)

等を呼ぶと、そもそもonClickが使われていない、
というようなメッセージが出ていたことを見落としていたようです。
これをよく調べてみたところ、どうやらimplementsがないと自分で書いたonClickを探しに行ってくれないようです。
したがって、正しい修正の仕方は、

public class MainActivity extends Activity implements OnClickListener{

 @Override
 protected coid onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  Button aBtn = (Button)findViewById(R.Id.aBtn);
  Button bBtn = (Button)findViewById(R.Id.bBtn);
  Button cBtn = (Button)findViewById(R.Id.cBtn);

  aBtn.setOnClickListener(this);
  bBtn.setOnClickListener(this);
  cBtn.setOnClickListener(this);

 }

/*-----省略-----*/

 @Override
 public void onClick(View v){
  if(v.getId() == R.id.aBtn){
   /*---処理---*/
  }
 }

}

って感じになります。
見にくい記事になって申し訳ない。。。。
まぁ、人に見せるために書いてないんでいいんですけど。。。。

終わります。