在android中定义button事件的最佳做法

我有一个由多个Button组成的XML定义的Layout

目前我在OnCreate方法中这样做来定义针对button的事件处理程序:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button newPicButton = (Button)findViewById(R.id.new_button); newPicButton.setOnClickListener(btnListener); ..... similarly for other buttons too ..... } 

ButtononClick事件中,我启动了一个相机Intent来获取图片,并在onActivityResultcallbackonActivityResult我再一次设置事件处理器,并设置View如下:

 protected void onActivityResult(int requestCode, int resultCode, Intent data) { setContentView(R.layout.main); Button newPicButton = (Button)findViewById(R.id.new_button); newPicButton.setOnClickListener(btnListener); ...similarly for other buttons too } 

我是Android新手,每次重新定义一个事件的方法对我来说似乎都很肮脏。 我想知道在像这样的场景中定义button事件处理程序的最佳做法是什么。

编辑:粘贴我的完整课程

 public class CameraAppActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button newPicButton = (Button)findViewById(R.id.new_button); newPicButton.setOnClickListener(btnListener); } //---create an anonymous class to act as a button click listener--- private OnClickListener btnListener = new OnClickListener() { public void onClick(View v) { //Intent newPicIntent = new Intent(v.getContext(), NewPictureActivity.class); //startActivityForResult(newPicIntent, 0); Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, 999); } }; protected void onActivityResult(int requestCode, int resultCode, Intent data) { setContentView(R.layout.main); Button newPicButton = (Button)findViewById(R.id.new_button); newPicButton.setOnClickListener(btnListener); //if I comment last two lines nothing happens when I click on button } 

主要的问题是

 setContentView(R.layout.main); Button newPicButton = (Button)findViewById(R.id.new_button); newPicButton.setOnClickListener(btnListener); 

重新注册onActivityResult事件..是正确的方法? 还是我做错了什么? 因为如果我不重新注册事件,当我点击button时没有任何反应。

为什么不在XML布局中注册onClick事件,然后在代码中处理它。 这是我将如何做到这一点:

 <Button android:id="@+id/my_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click me" android:onClick="onBtnClicked"> </Button> 

现在创build一个处理点击的方法

 public void onBtnClicked(View v){ if(v.getId() == R.id.my_btn){ //handle the click here } } 

或者,您可以分别为代码中的每个项目设置OnClickListener。 然后使用if / else或switch语句来确定原点。

这样你可以有一个方法来处理一个布局的所有button。

更新:
虽然这是一个有效的方法,我强烈build议第二个选项。 它更清洁,更容易维护,特别是在处理碎片时。

以下是使用代码的最佳方法:

  public class MyTest extends Activity implements OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... some other code here to init the layout Button btn1 = (Button)findViewById(R.id.button1); Button btn2 = (Button)findViewById(R.id.button2); btn1.setOnClickListener(this); btn2.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.button1: break; case R.id.button2: break; } } } 

如果你想分离实现(当你想在别的地方使用相同的类代码,把它移动到另一个单独的类文件等等),但是一般情况下,如果你正在做的事情与接口你正在使用的当前活动和onClick实现依赖于它参照在那里定义的对象运行,你应该使用我build议的方法。

创build类接口只有当你想要实现单独的类或活动之间的通信并保持分离时才是好的。 除了这是一个不好的做法,为此创build子类。

这是最好的方法

 @Override public void onCreate(Bundle savedInstanceState) { button1.setOnClickListener(onClickListener); button2.setOnClickListener(onClickListener); button3.setOnClickListener(onClickListener); } private OnClickListener onClickListener = new OnClickListener() { @Override public void onClick(final View v) { switch(v.getId()){ case R.id.button1: //DO something break; case R.id.button2: //DO something break; case R.id.button3: //DO something break; } } }; 

没有最佳做法的定义。 这很大程度上取决于用例。 您可以使用Button的onClick属性在您的XML布局中定义它们。

XML示例:

 <!-- Stuff --> <Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me!" android:onClick="myClickMethod" /> 

Java示例:

 // stuff public void myClickMethod(View v) { // more stuff } 

这样你就不必自己实现OnClickListener 。 您可以为每个Button分配相同的onClick方法,然后根据每个视图来决定要触发的操作,或者您可以为每个Button分别设置一个方法。

一般来说,我build议不要将一个OnClickListener用于多个Button。 如果你使用描述性的名字,那么每个听众应该做的事情就变得容易了。

我喜欢使用黄油刀的“现代”DI方式:

  1. 宣布你的看法
 @InjectView(R.id.buttonAlert) Button buttonAlert; 
  1. 注入所有注释的资源
 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); } 
  1. 注释并实施您的onClick方法
 @OnClick(R.id.buttonAlert) public void alertClicked(View v){ // your logic } 

@Hasan这是我find的最好的方法,每一次都是完美无缺的。

  • 在Layout.xml中定义button的onClick

      <Button android:id="@+id/Button01" android:onClick="@string/method" android:focusable="true" android:clickable="true" "> </Button> 
  • 在R.string文件中添加以下行

string name =“method”> buttonFunction

  • 在sample.java文件中,R.string中的函数定义将在点击button时调用,它应该看起来像这样

    公共无效buttonFunction(视图视图){/ /做点什么你喜欢点击button}

你的活动应该实现OnClickListener,你应该把所有的事件处理都写在一个OnCLick()方法中。

问题是newPicButtonbutton的对象被创build为一个局部对象,只有在onCreate函数的作用域内才有效,只要代码退出该函数,garabage收集器就会释放该button的对象。 你需要做的是在任何方法之外声明newPicButton对象,然后在onCreate方法中为它分配一个监听器。 这将解决你的问题,我希望我已经解释了为什么没有反应,当你在onActivityResult方法中删除newPicButton的代码:)

我知道这是旧的,但如果有人想知道为什么你不能从onActivityResult ,这是因为该button为空。 如果您再次初始化它(就像您在onCreate ),您可以添加侦听器。 但是,要小心,所有其他东西也是空的,所以如果你从EditText中获取数据,例如,你也必须初始化它(简单的检查对象是否为null) )。

我是这样做的:

  1. 在buttonXML文件中设置android:onClick =“onClick”。
  2. 在你的Activity中实现View.OnClickListener。
  3. 在onClick方法中使用切换键(如下所示)。

@覆盖

 public void onClick(View view) { Intent intent; switch(view.getId()){ case R.id.home_button: //DO something intent = new Intent(HashTagActivity.this,MainActivity.class); startActivity(intent); break; case R.id.back_button: //DO something intent = new Intent(HashTagActivity.this,ClassActivity.class); startActivity(intent); break; case R.id.favorite_button: //DO something break; case R.id.copy_button: //DO something break; } } 

它工作很好。