web-dev-qa-db-ja.com

Android:ボタンクリックの処理方法

JavaでもAndroidでもない分野で確かな経験があるので、Androidを学んでいます。

さまざまな分野で多くの混乱がありますが、そのうちの1つはボタンクリックの処理方法です。少なくとも4つの方法があります(!!!)、簡単にリストされています ここ

一貫性を保つために、それらをリストします。

  1. アクティビティにView.OnClickListenerクラスのメンバーを用意し、それをonClickアクティビティメソッドでonCreateロジックを処理するインスタンスに割り当てます。

  2. 「onCreate」アクティビティメソッドで「onClickListener」を作成し、setOnClickListenerを使用してボタンに割り当てます。

  3. アクティビティ自体に「onClickListener」を実装し、「this」をボタンのリスナーとして割り当てます。アクティビティにボタンがほとんどない場合、ボタンIDを分析して適切なボタンの「onClick」ハンドラを実行する必要があります

  4. 'onClick'ロジックを実装するアクティビティにパブリックメソッドを用意し、それをアクティビティxml宣言のボタンに割り当てます。

質問#1:

これらはすべてメソッドですか、他のオプションはありますか? (私は他に何も必要ありません、ただ興味があります)

私にとって、最も直感的な方法は最新の方法です。入力するコードの量が最小限で、最も読みやすいです(少なくとも私にとって)。

しかし、私はこのアプローチが広く使われているとは思わない。それを使用することの短所は何ですか?

質問2:

これらの各方法の長所と短所は何ですか?あなたの経験または良いリンクを共有してください。

フィードバックは大歓迎です!

追伸私はグーグルでこのトピックの何かを見つけようとしましたが、私が見つけた唯一のことは、それがなぜ良いのか悪いのかではなく、それを行う方法の説明です。

87
Budda

質問1:残念ながら、最も直感的だと言うのはAndroidでの使用が最も少ないということです。私が理解しているように、UI(XML)と計算機能(Javaクラスファイル)を分離する必要があります。また、デバッグが容易になります。実際、このように読み、Android imoについて考える方がはるかに簡単です。

質問2:主に使用される2つは#2と#3であると思います。例としてButton clickButtonを使用します。

2

匿名クラスの形式です。

Button clickButton = (Button) findViewById(R.id.clickButton);
clickButton.setOnClickListener( new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                ***Do what you want with the click here***
            }
        });

これは、ボタン変数がfindViewByIdで設定された場所のすぐ隣にonClickメソッドがあるため、私のお気に入りです。このclickButtonボタンビューを扱うすべてのものがここにあるのは、非常にきちんと整理されているようです。

同僚がコメントしている短所は、onclickリスナーを必要とする多くのビューがあると想像してください。 onCreateの長さが非常に長くなることがわかります。だから彼が使用したい理由:

3

5つのclickButtonがあるとします。

アクティビティ/フラグメントがOnClickListenerを実装していることを確認してください

// in OnCreate

Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
Button mClickButton4 = (Button)findViewById(R.id.clickButton4);
mClickButton4.setOnClickListener(this);
Button mClickButton5 = (Button)findViewById(R.id.clickButton5);
mClickButton5.setOnClickListener(this);


// somewhere else in your code

public void onClick(View v) {
    switch (v.getId()) {
        case  R.id.clickButton1: {
            // do something for button 1 click
            break;
        }

        case R.id.clickButton2: {
            // do something for button 2 click
            break;
        }

        //.... etc
    }
}

私の同僚が説明しているこの方法は、すべてのonClick計算が1つの場所で処理され、onCreateメソッドを混雑させないため、彼の目にはすっきりしています。しかし、私が見る欠点は、それが:

  1. 自分自身を見る、
  2. また、onClickメソッドで使用されるonCreateにある他のオブジェクトは、フィールドにする必要があります。

さらに情報が必要な場合はお知らせください。それはかなり長い質問なので、私はあなたの質問に完全には答えませんでした。そして、もし私がいくつかのサイトを見つけたら、答えを拡大します。今、私はただいくつかの経験をしています。

133
D. Tran

#1レイアウト上にボタンが生成されていないときに頻繁に最後のボタンを使用します(明らかに静的です)。

ProGuardのように source obfuscater を使用する場合、アクティビティでこれらのメソッドを難読化されないようにマークする必要があるため、実際にビジネスアプリケーションで使用する場合は、ここで特に注意してください。

このアプローチである種のコンパイル時セキュリティをアーカイブするには、 Android Lint (- example )をご覧ください。


#2allメソッドの長所と短所はほぼ同じであり、レッスンは次のようになります。

これまでで最も適切なもの、または最も直感的に使用できるものを使用してください。

同じOnClickListenerを複数のボタンインスタンスに割り当てる必要がある場合は、クラススコープ(#1)に保存します。 Buttonの単純なリスナーが必要な場合は、匿名実装を作成します。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Take action.
    }
});

私はアクティビティにOnClickListenerを実装しない傾向があり、これは時々少し混乱します(特に他の複数のイベントハンドラを実装し、thisが何をしているのか誰も知らない場合)。

10
Lukas Knuth

私はオプション4を好みますが、Grails、Groovy、およびJavaFXであまりにも多くの作業を行うため、直感的に理にかなっています。ビューとコントローラー間の「マジック」接続はすべて共通です。メソッドに適切な名前を付けることが重要です。

ビューで、ボタンまたはその他のウィジェットにonClickメソッドを追加します。

    Android:clickable="true"
    Android:onClick="onButtonClickCancel"

次に、クラスでメソッドを処理します。

public void onButtonClickCancel(View view) {
    Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show();
}

繰り返しますが、とにかくやるべきことをメソッドに明確に名前を付けてください。そうすれば、メンテナンスが自然になります。

1つの大きな利点は、メソッドの単体テストを今すぐ作成できることです。オプション1はこれを実行できますが、2と3はより困難です。

8
Steve Gelman

最もよく使われる方法は、匿名宣言です

    Button send = (Button) findViewById(R.id.buttonSend);
    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // handle click
        }
    });

また、後でView.OnClickListenerオブジェクトを作成してボタンに設定することもできますが、たとえばonClickメソッドをオーバーライドする必要があります

View.OnClickListener listener = new View.OnClickListener(){
     @Override
        public void onClick(View v) {
            // handle click
        }
}   
Button send = (Button) findViewById(R.id.buttonSend);
send.setOnClickListener(listener);

アクティビティがOnClickListenerインターフェイスを実装する場合、アクティビティレベルでonClick(View v)メソッドをオーバーライドする必要があります。次に、このアクティビティはボタンのリスナーとして割り当てることができます。これは、すでにインターフェイスを実装し、onClick()メソッドをオーバーライドしているためです。

public class MyActivity extends Activity implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // handle click
    }


    @Override
    public void onCreate(Bundle b) {
        Button send = (Button) findViewById(R.id.buttonSend);
        send.setOnClickListener(this);
    }

}

(imho)複数のボタンに同じハンドラーがあり、アクティビティクラスで1つのメソッドを宣言し、このメソッドをxmlレイアウトの複数のボタンに割り当てることができる場合に使用される4番目のアプローチ、1つのボタンに1つのメソッドを作成することもできますが、この場合はアクティビティクラス内でハンドラを宣言することを好みます。

4
Georgy Gobozov

オプション1および2では、コードを混乱させる内部クラスを使用します。オプション2は、ボタンごとに1つのリスナーが存在するため、やや面倒です。ボタンの数が少ない場合、これで問題ありません。オプション4の場合、xmlおよびJavaコードに戻って4番目に戻る必要があるため、これはデバッグが困難になると思います。複数のボタンクリックを処理する必要がある場合、個人的にオプション3を使用します。

1
CChi

私のサンプル、Android Studio 2.1でテスト済み

XMLレイアウトの定義ボタン

<Button
    Android:id="@+id/btn1"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content" />

Java脈動検出

Button clickButton = (Button) findViewById(R.id.btn1);
if (clickButton != null) {
    clickButton.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /***Do what you want with the click here***/
        }
    });
}
1
Webserveis

質問2で述べたように、物事を簡単にするために、このようなラムダメソッドを使用して変数メモリを節約し、ビュークラスで上下にナビゲートしないようにすることができます

//method 1
findViewById(R.id.buttonSend).setOnClickListener(v -> {
          // handle click
});

ただし、メソッドでボタンにクリックイベントを一度に適用する場合。

@Dが質問3を利用できます。トランの答え。ただし、View.OnClickListenerを使用してビュークラスを実装することを忘れないでください。

質問#3を適切に使用するために

1
Michael

ステップ1:XMLファイルの作成:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <Button
        Android:id="@+id/btnClickEvent"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Click Me" />
</LinearLayout>

ステップ2:MainActivityの作成:

package com.scancode.acutesoft.telephonymanagerapp;

import Android.app.Activity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

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

        btnClickEvent = (Button) findViewById(R.id.btnClickEvent);
        btnClickEvent.setOnClickListener(MainActivity.this);

    }

    @Override
    public void onClick(View v) {
        //Your Logic
    }
}

HappyCoding!

0
Manikanta Reddy

質問#1-ビューのクリックを処理する唯一の方法です。

質問2 -
Option#1/Option#4-オプション#1とオプション#4の間に大きな違いはありません。私が見る唯一の違いは、1つのケースではアクティビティがOnClickListenerを実装しているのに対して、もう1つのケースでは匿名実装があるということです。

Option#2-このメソッドでは、匿名クラスが生成されます。複数のボタンがある場合、複数回行う必要があるため、この方法は少し面倒です。匿名クラスの場合、メモリリークの処理には注意する必要があります。

オプション#3-ただし、これは簡単な方法です。通常、プログラマは作成するまでメソッドを使用しないようにしているため、このメソッドは広く使用されていません。ほとんどの人がOption#4を使用するのを見るでしょう。コードの観点からすっきりしているからです。

0
Gaurav Arora

他のMVVMフレームワークを使用したことのある人にとってこのプロセスを非常に親しみやすいものにするさまざまなライブラリの形で利用可能なオプションもあります。

https://developer.Android.com/topic/libraries/data-binding/

公式ライブラリの例を示します。これにより、次のようなボタンをバインドできます。

<Button
    Android:text="Start second activity"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:onClick="@{() -> presenter.showList()}"
/>
0
Ryan The Leach