我在XML中定义了一个Layout
,它由几个Button
组成。
目前我在OnCreate
方法中执行此操作,以针对按钮定义事件处理程序:
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
.....
}
在Button
的{{1}}事件中,我启动了一个相机onClick
来获取图片并在Intent
回调中我再次设置事件处理程序设置onActivityResult
就像这样:
View
我是android新手,这种每次重新定义事件的方法对我来说都很脏。我想知道在这样的场景中定义按钮事件处理程序方面的最佳实践是什么。
编辑:粘贴我的完整课程
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
}
主要问题是
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);
内的事件..这是正确的方法吗?或者我做错了什么?因为如果我不重新注册事件,当我点击按钮时没有任何事情发生。
答案 0 :(得分:64)
为什么不在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>
现在创建一个处理点击的方法
public void onBtnClicked(View v){
if(v.getId() == R.id.my_btn){
//handle the click here
}
}
或者,您可以为代码中的每个项单独设置OnClickListener。然后使用if / else或switch语句确定原点。
这样你可以有一个方法来处理一个布局中的所有按钮。
<强>更新强>
虽然这是一种有效的方法,但我强烈推荐第二种方法。它更清洁,更易于维护,尤其是在处理碎片时。
答案 1 :(得分:39)
以下是使用代码的最佳方法:
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实现依赖于它运行时参考那里定义的对象你应该使用我建议的方法。
只有在想要实现单独的类或活动之间的通信并使事物分开时,才能创建类接口。除此之外,这是一个为此创建子类的不良做法。
答案 2 :(得分:12)
这是最好的方法
@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;
}
}
};
答案 3 :(得分:8)
没有定义最佳实践。它在很大程度上取决于用例。您可以使用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设置单独的方法。
一般来说,我建议不要将一个OnClickListener
用于多个Button。如果你使用描述性名称,那么你应该更容易理解每个听众应该做什么。
答案 4 :(得分:7)
我喜欢&#34;现代&#34; DI方式使用Butter Knife:
@InjectView(R.id.buttonAlert)
Button buttonAlert;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
}
@OnClick(R.id.buttonAlert)
public void alertClicked(View v){
// your logic
}
答案 5 :(得分:2)
@Hasan这是我找到的最好的方法,每次都能完美地为我服务。
在Layout.xml中定义按钮的onClick
<Button android:id="@+id/Button01"
android:onClick="@string/method"
android:focusable="true" android:clickable="true"
">
</Button>
在R.string文件中添加以下行
string name =&#34; method&#34;&gt; buttonFunction
在sample.java文件中,单击按钮时将调用R.string中的函数define,它应该看起来像
public void buttonFunction(View view){ //点击按钮即可 }
答案 6 :(得分:0)
您的Activity应该实现OnClickListener,您应该为单个OnCLick()方法中的所有按钮编写所有事件处理。
答案 7 :(得分:0)
问题是按钮newPicButton的对象是作为本地对象创建的,该对象仅在函数onCreate的范围内有效,并且一旦代码退出该函数,garabage collector就会释放按钮的对象。你需要做的是在任何方法之外声明newPicButton对象,然后在onCreate方法中为它分配一个监听器。这将解决您的问题,我希望我已经解释了为什么在onActivityResult方法中删除newPicButton的代码时没有任何反应:)
答案 8 :(得分:0)
我知道这已经过时了,但是如果有人想知道为什么你不能从onClickListener
添加onActivityResult
,那是因为按钮为空。如果再次初始化它(就像在onCreate
中那样),则可以添加侦听器。但要小心,其他一切也都是null,所以如果你从EditText
获取数据,你也必须初始化它(简单检查一下lisneter中的对象是否为null)会做的伎俩)。
答案 9 :(得分:0)
我是这样做的:
@覆盖
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;
}
}
效果很好。