XMLでのAndroidonClickとOnClickListener


86

以前にも同じような言葉で質問されたことがあると思いますが、これは違います。私はAndroidアプリの開発にかなり慣れていないので、android:onclick=""XML属性とsetOnClickListenerメソッドの違いについて3つの質問があります。

  1. 2つの違いは何ですか?2つの実装の違いは、コンパイル時または実行時、あるいはその両方で見つかりますか?

  2. どのユースケースがどの実装に有利ですか?

  3. Androidでフラグメントを使用すると、実装の選択にどのような違いがありますか?


1
#2の場合:onclickすべてのクラスがそのメソッドを実装していることを確認する必要があるため、xmlを使用するときは注意が必要です。これは、レイアウトを複数回使用していることを前提としています。ただし、メソッドがそれを実装するすべてのクラスにあることを確認するためのJavaインターフェースがあれば、心配する必要はありません。
uxonith 2014年

あなたが説明したようなJavaインターフェースを持つことは、OnClickListenerを拡張または実装することとほとんど同じではないでしょうか?
KG6ZVP 2014年

以前に調べたことがありますが、好みよりも少し多いと思いますが、久しぶりに申し訳ありません。android:onclick便利なときが好きですが、問題が発生することもあり、それも思い出せません:)
Uxonith 2014年

xml onClickは、APIレベル19で動的に拡張されるネストされたレイアウト要素では機能しません
Amit Kaushik 2016

1
android:onClickを実装している他の人のコードを見たことはめったにありません。他の人のコードを見ると、最も混乱します。setOnClickListenerのすべての可能性があるわけではないので、私の意見ではほとんどの人がsetOnClickListenerのみを使用しています
クリスチャン

回答:


122

OnClickListenerとOnClickの違い:

  • OnClickListenerは、実装する必要のあるインターフェースであり、Javaコードのビューに設定できます。
  • OnClickListenerは、誰かが実際にクリックするのを待つものであり、onclickは、誰かがクリックしたときに何が起こるかを決定します。
  • 最近、androidはandroid:onclickと呼ばれるxml属性をビューに追加しました。これを使用すると、インターフェイスを実装しなくても、ビューのアクティビティでクリックを直接処理できます。
  • 必要に応じて、あるリスナー実装を別のリスナー実装と簡単に交換できます。
  • OnClickListenerを使用すると、クリックイベントのアクション/動作を、イベントをトリガーするビューから分離できます。単純なケースではこれはそれほど大きな問題ではありませんが、複雑なイベント処理では、コードの可読性と保守性が向上する可能性があります
  • OnClickListenerはインターフェースであるため、それを実装するクラスには、イベントを処理するために必要なインスタンス変数とメソッドを決定する際の柔軟性があります。繰り返しますが、これは単純なケースでは大したことではありませんが、複雑なケースでは、イベント処理に関連する変数/メソッドを、イベントをトリガーするビューのコードと混同する必要はありません。
  • XMLレイアウトの関数バインディングを使用したonClickは、onClickとそれが呼び出す関数の間のバインディングです。onClickが機能するためには、関数に1つの引数(ビュー)が必要です。

どちらも同じように機能しますが、一方はJavaコードを介して設定され、もう一方はxmlコードを介して設定されます。

setOnClickListenerコードの実装:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

XML実装:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

パフォーマンス:

どちらもパフォーマンスは同じです。Xmlは、コンパイル中にバイナリコードに事前に解析されます。したがって、Xmlにはオーバーヘッドはありません。

制限:

android:onClickはAPIレベル4以降を対象としているため、1.6未満をターゲットにしている場合は、使用できません。


`XMLはコンパイル中にバイナリコードに事前に解析されます`このステートメントは正確にはどういう意味ですか?マニフェストファイルにandroid:onClickが含まれているapkのdexcodeを見たのですが、リスナー
VicX 2015

素晴らしい説明。+1
ジアウルラフマン2016年

1
実際、XMLにはいくらかのオーバーヘッドがあります。ボタンを初めてクリックすると、リフレクションを使用して、呼び出す必要のあるメソッドが決定されます。ただし、これはほとんどのユースケースではおそらく無視できます(そして、時期尚早の最適化はすべての悪の根源です)。
Yoel 2016年

21

誰もこれについて話していないことにショックを受けましたが、注意してくださいandroid:onClick。XMLはクリックを処理する便利な方法のようですが、setOnClickListener実装はを追加する以外に何か追加のことを行いonClickListenerます。確かに、それはビュープロパティを置きますclickableをtrueにします。

ほとんどのAndroid実装では問題にならないかもしれませんが、電話コンストラクターによると、ボタンは常にデフォルトでclickable = trueになっていますが、一部の電話モデルの他のコンストラクターでは、ボタン以外のビューでデフォルトのclickable = falseになっている場合があります。

したがって、XMLを設定するだけでは不十分であり、android:clickable="true"ボタン以外を追加することを常に考える必要があります。デフォルトがclickable = trueであるデバイスがあり、このXML属性を一度も入力するのを忘れた場合、気付かないでしょう。実行時に問題が発生しますが、顧客の手に渡ると市場でフィードバックが得られます。

さらに、proguardがXML属性とクラスメソッドをどのように難読化して名前を変更するかについては確信が持てないため、100%安全ではないため、いつかバグが発生することはありません。

したがって、問題が発生したくなく、考えたくない場合はsetOnClickListener、アノテーション付きのButterKnifeなどのライブラリを使用することをお勧めします。@OnClick(R.id.button)


1
使用時の難読化によりバグが発生した(またはどこかで見た)経験はありますandroid:onClickか?
Akram 2018

ありがとうございます!あなたの答えはとても役に立ちます!
Yi Shen

12

単に:

あなたが持っている場合はandroid:onClick = "someMethod" 、XMLで、それが探しpublic void someMethodあなたのActivityクラスインチ アクティビティから直接OnClickListener呼び出され、特定のにリンクされています。たとえば、以下のコードでは、が押されたときに何をしなければならないかが示されています。ViewsomeButton.setOnClickListenersomeButton

それが役に立てば幸い :)


4

前に述べたように、どちらもイベント(この場合は「クリック」イベント)に応答してロジックを追加する方法です。

HTML / JavaScriptの世界と同じように、ロジックとプレゼンテーションを分離します。プレゼンテーション用にXMLを残し、コードを使用してイベントリスナーを追加します。


1
同意しました。単純な動作をする非常に小さなアプリでない限り、実行するコードはすべて、できれば別々のメソッドを使用して、別々に整理する必要があります
OzzyTheGiant

0

1つのメソッドのみを使用するボタンが複数ある場合は、Javaで実行することをお勧めします。ただし、特定のメソッドが1つあるボタンがある場合は、XMLのonClickの方が適しています。


0

実行時にButtonをインスタンス化する場合や、Fragmentサブクラスでクリック動作を宣言する必要がある場合など、正当な理由がない限り、常にandroid:onClick属性を使用する方が便利です。


3
android:onClickを実装している他の人のコードを見たことはめったにありません。他の人のコードを見ると、最も混乱します。setOnClickListenerのすべての可能性があるわけではないので、私の意見ではほとんどの人がsetOnClickListenerのみを使用しています
クリスチャン

0

プログラムでを設定する理由はいくつかありますOnClickListener。1つ目は、アプリの実行中にボタンの動作を変更したい場合です。ボタンを別のメソッドに完全に向けるOnClickListenerことも、何もしないように設定してボタンを無効にすることもできます。

onClick属性を使用してリスナーを定義すると、ビューはそのホストアクティビティでのみその名前のメソッドを探します。プログラムでを設定するとOnClickListener、ホストアクティビティ以外の場所からボタンの動作を制御できます。これはFragments、基本的にミニアクティビティであるを使用するときに非常に関連性が高くなり、独自のライフサイクルでビューの再利用可能なコレクションを構築して、アクティビティにまとめることができます。フラグメントOnClickListenersはアクティビティではないため、ボタンを制御するために常に使用する必要があり、onClickで定義されたリスナーは検索されません。


-2

それらの主な違いは次のとおりです。

OnClick:ボタンを指でクリックしたとき。

OnClickListner:さまざまなコードで実装されるのは幅広い選択肢かもしれません。

たとえば、url "ymail.com"と入力すると、yahooはブラウザからユーザー名とパスワードを検索し、[状態]ボタンをクリックしてメールを開きます。このアクションは、onClickListenerでのみ実装する必要があります。

これが私の考えです!


これは興味深いですが、それだけではありません。あなたはむしろコメントであるべきでした。
ダカティン2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.