Android:如何处理button点击

在非Java和非Android领域有丰富的经验,我正在学习Android。

我对不同领域有很多困惑,其中之一是如何处理button点击。 至less有4种方式(!!!),他们在这里简要列出

为了一致性的目的,我将列出他们:

  1. 在活动中拥有View.OnClickListener类的成员,并将其分配给将在onCreate活动方法中处理onClick逻辑的实例。

  2. 在“onCreate”活动方法中创build“onClickListener”,并使用setOnClickListener将其分配给button

  3. 在活动本身中实现“onClickListener”,并将“this”作为button的侦听器。 对于活动只有less量button的情况,应该分析buttonID以执行适当button的“onClick”处理程序

  4. 对实现“onClick”逻辑的活动有公共方法,并将其分配给活动xml声明中的button

问题1:

那些所有的方法,有没有其他的select? (我不需要任何其他的,只是好奇)

对我来说,最直观的方法是最新的:它需要input最less的代码,并且是最可读的(至less对我来说)。

虽然,我不认为这种方法被广泛使用。 有什么缺点使用它?

问题2:

每种方法有哪些优点/缺点? 请分享您的经验或一个很好的链接。

欢迎任何反馈!

PS我已经尝试Google,并为这个主题find一些东西,但我发现的唯一的东西是描述“怎么做”,而不是为什么好或坏。

问题1:不幸的是,你所说的最直观的是Android中最less使用的。 据我所知,你应该分开你的用户界面(XML)和计算function(Java类文件)。 这也使得debugging更容易。 实际上,阅读这种方式比较容易,并考虑Android imo。

问题2:我相信主要使用的是#2和#3。 我将使用一个buttonclickButton为例。

2

是一个匿名类的forms。

 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*** } }); 

这是我最喜欢的,因为它的onClick方法就在findViewById设置的buttonvariables的旁边。 似乎非常整齐,所有处理这个clickButtonbutton视图的东西都在这里。

我的同事评论的一个骗局是,想象你有许多需要onclick监听器的观点。 你可以看到你的onCreate会变得很长。 所以为什么他喜欢用:

3

假设你有5个clickButtons:

确保你的Activity / Fragment实现了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计算都是在一个地方处理的,而不是拥挤的onCreate方法,所以我的同事解释说这种方式更整洁。 但是我看到的缺点是,

  1. 观看自己,
  2. 而onClick方法所使用的onCreate中可能存在的任何其他对象都必须放入一个字段中。

让我知道你是否想要更多的信息。 我没有完全回答你的问题,因为这是一个相当长的问题。 如果我find一些网站,我会扩大我的答案,现在我只是给一些经验。

#1我经常使用最后一个布局上没有生成的button(但显然是静态的)。

如果您在实践和商业应用程序中使用它,请特别注意这一点,因为当您使用ProGuard之类的源代码混淆器时 ,您需要在活动中标记这些方法以免被混淆。

为了使用这种方法来存档某种编译时安全性,请查看Android Lint ( 示例 )。


#2 所有方法的优点和缺点几乎相同,教训应该是:

使用什么是最合适的或感觉最直观的。

如果必须将相同的OnClickListener分配给多个button实例,请将其保存在类范围内(#1)。 如果你需要一个简单的button的侦听器,做一个匿名实现:

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

我倾向于不在活动中实现OnClickListener ,这OnClickListener会引起混淆(尤其是当您实现多个其他事件处理程序时,并且没有人知道this是干什么的)。

最常用的方式是匿名声明

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

您也可以创buildView.OnClickListener对象,稍后将其设置为button,但您仍然需要重写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)方法。 然后你可以将这个活动作为监听器来监听button,因为它已经实现了接口并且覆盖了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)第4种方法,当多个button具有相同的处理程序时,您可以在活动类中声明一个方法,并将此方法分配给xml布局中的多个button,也可以为一个button创build一个方法,但在这种情况下,我更喜欢在活动类中声明处理程序。

我更喜欢选项4,但对我来说,这是直觉,因为我在Grails,Groovy和JavaFX中做了太多的工作。 视图与控制器之间的“魔术”连接是共同的。 很好的命名方法很重要:

在视图中,将onClick方法添加到button或其他小部件:

  android:clickable="true" android:onClick="onButtonClickCancel" 

然后在课堂上,处理方法:

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

再次,清楚地说出方法的名称,无论如何你应该做的,维护变成第二性质。

一个很大的优点是你现在可以为这个方法编写unit testing。 选项1可以做到这一点,但2和3更难。

选项1和2涉及使用内部类,这将使代码种类混乱。 选项2有点乱,因为每个button都会有一个监听器。 如果你有less量的button,这是好的。 对于选项4,我认为这将是更难以debugging,因为你将不得不回头和第四次的XML和Java代码。 我个人使用选项3,当我必须处理多个button点击。

我的示例,在Android Studio 2.1中testing

在xml布局中定义button

 <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 – 这是处理查看点击的唯一方法。

问题2 –
选项#1 /选项#4 – 选项#1和选项#4没有太大的区别。 我看到的唯一区别是在一种情况下,活动正在实现OnClickListener,而在另一种情况下,会有一个匿名的实现。

选项#2 – 在这种方法中,将会生成一个匿名类。 这个方法有点笨拙,因为如果你有多个button,你需要多次执行。 对于匿名类,你必须小心处理内存泄漏。

选项#3 – 虽然这是一个简单的方法。 通常,程序员在编写程序之前不要使用任何方法,因此这种方法没有被广泛使用。 你会看到大多数人使用选项#4。 因为它在代码方面更干净。

第1步:创build一个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步:创buildMainActivity

 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