« ThemeとStyle | トップページ | 割り勘計算機(5) »

2011年2月 7日 (月)

ListViewの中のボタンからActivityにイベントを通知する

Developersサイトでメソッドを見つけたので検証してみました。

ListViewの中にボタンがあると、ListViewのOnItemClickはクリックイベントを拾えなくなります。その代わり、ボタンのクリックでイベントが通知されるのですが、ボタンはListViewの行の数だけできるのでそれを受け取るにはリスナーを経由する必要があります。

すでにOnItemClickListenerがあるわけで、それに渡せばいいんじゃない?というか、OnIemClickListenerのidパラメタてなんに使うの?という疑問の答えがこれです。プログラムそのものはチュートリアルのListViewサンプルの改造です。

public class main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        ListView lv ;
        final LayoutInflater minf = LayoutInflater.from(this);
        ViewGroup rootvg = (ViewGroup)minf.inflate(R.layout.main, null);
        lv = (ListView) rootvg.findViewById(android.R.id.list);
        lv.setAdapter(new ArrayAdapter(this,R.layout.list_item, COUNTRIES){
                  public View getView(final int pos,View cv,final ViewGroup parent){
                  cv = minf.inflate(R.layout.button_list, null);
                  TextView co = (TextView)cv.findViewById(R.id.TextView01);
                  co.setText(COUNTRIES[pos]);
                  Button bo = (Button)cv.findViewById(R.id.Button01);
                  bo.setOnClickListener(new OnClickListener(){
                        public void onClick(View v){
                              ((ListView) parent).performItemClick(v, pos, (long)0);
                        }
                  });
                  return cv;
            }
        });
        setContentView(rootvg);
        lv.setTextFilterEnabled(true);
        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent,View view, int position, long id) {
                  Toast.makeText(getApplicationContext(),((TextView)view).getText(), Toast.LENGTH_LONG)
                  .show();
            }
        });
    }

かなり入れ子になっているので見づらくて申し訳ないです。つまり、ArrayAdapterのgetViewの中でTextViewとButtonが並んだ行をinflateして、ボタンにonClickListenerをつけます。そして、その中でperfomItemClickすればActivityでセットしたOnItemClickListenerが呼ばれます。

分かってみればそれだけのことですが。 もちろん、ボタンが複数あってもidをきちんと設定して判定すればどのボタンが押されたか分かります。

« ThemeとStyle | トップページ | 割り勘計算機(5) »

コメント

この件、自分もなかなかうまくいかず、
人に聞いてもネットを探してもよくわからなかったので、非常に困ってました。
メインのクラスとArrayAdapterクラスを分けて設計していたので、
ArrayAdapterクラスのの中でボタンを押した処理を書くと
局所変数でいいものを両方のクラスで共有化することになり、美しさにかけるコードになってしまい、
絶対にボタンイベントを起こすメソッドがあってもおかしくない、あるべきだと、
ブチブチいいながらコードを書いていました。

偶然このブログに見つかり、非常にうれしいです。即座にブックマークしました。

どうもありがとうございます。

私も悩んでいました。単純な文字列だけを表示するListViewのサンプルではうまくクリックイベントが取得できるのに、複数のパーツで構成すると、イベントが取れない。調べたところ、各パーツではクリックイベントが取れている。行としてイベントが欲しい。どうやってとばそうか?カスタムイベントをつくらないといけないのか?そんなはずないよなぁ。。。どうするんだろう?っと。
performItemClickというメソッドがあったんですね。
お陰様でうまくイベントを処理することができるようになりました。ありがとうございます。
あと1点、どうにかしたいことが残っています。行をクリックしたとき、クリックの対象となったパーツが反応します。できれば、行全体を一瞬反転させたいのですが、なにかうまい方法はないのでしょうか?ご存知でしたらご教示ください。

idの使い方が分かりました!ありがとうございますhappy01

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/60027/50805982

この記事へのトラックバック一覧です: ListViewの中のボタンからActivityにイベントを通知する:

« ThemeとStyle | トップページ | 割り勘計算機(5) »