从我所读到的,你可以用两种方式为按钮分配onClick处理程序。

使用android:onClick XML属性,你只是使用一个公共方法的名称与signaturevoid名称(View v)或通过使用setOnClickListener方法,你传递一个实现OnClickListener接口的对象。后者通常需要一个匿名类,我个人不喜欢(个人口味)或定义一个实现OnClickListener的内部类。

通过使用XML属性,你只需要定义一个方法而不是一个类 想知道同样的事情是否可以通过代码而不是在XML布局中完成。


当前回答

不,通过代码是不可能的。当你定义Android:onClick="someMethod"属性时,Android只是实现了OnClickListener。

这两个代码段是相等的,只是以两种不同的方式实现。

代码实现

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
}

上面是OnClickListener的代码实现。这是XML实现。

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 -->

在后台,Android只做Java代码,在点击事件时调用你的方法。

注意,使用上面的XML, Android将只在当前Activity中寻找onClick方法myFancyMethod()。如果你正在使用片段,记住这一点很重要,因为即使你使用片段添加上面的XML, Android也不会在用于添加XML的片段的.java文件中查找onClick方法。

我注意到另一件重要的事情。你提到你不喜欢匿名方法。你的意思是说你不喜欢匿名课程。

其他回答

另一种设置on click侦听器的方法是使用XML。只需添加android:onClick属性到你的标签。

尽可能在匿名Java类上使用xml属性“onClick”是一个很好的实践。

首先,让我们看看代码中的区别:

XML属性/ onClick属性

XML部分

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/button1" 
    android:onClick="showToast"/>

Java部分

public void showToast(View v) {
    //Add some logic
}

匿名Java类/ setOnClickListener

XML部分

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

Java部分

findViewById(R.id.button1).setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Add some logic
        }
});

下面是使用XML属性而不是匿名Java类的好处:

With Anonymous Java class we always have to specify an id for our elements, but with XML attribute id can be omitted. With Anonymous Java class we have to actively search for the element inside of the view (findViewById portion), but with the XML attribute Android does it for us. Anonymous Java class requires at least 5 lines of code, as we can see, but with the XML attribute 3 lines of code is sufficient. With Anonymous Java class we have to name of our method “onClick", but with the XML attribute we can add any name we want, which will dramatically help with the readability of our code. Xml “onClick” attribute has been added by Google during the API level 4 release, which means that it is a bit more modern syntax and modern syntax is almost always better.

当然,并不总是可以使用Xml属性,以下是我们不选择它的原因:

如果我们使用片段。onClick属性只能添加 一个活动,所以如果我们有一个片段,我们将不得不使用 匿名类。 如果我们想移动onClick侦听器到一个单独的类 (也许如果它非常复杂和/或我们想重新使用它 的不同部分),那么我们就不想使用 XML属性。

通过使用XML属性,您只需要定义一个方法而不是 一个类,所以我想知道如果同样可以通过代码而不是在 XML布局。

是的,你可以让你的片段或活动实现视图。OnClickListener

当你在代码中初始化你的新视图对象时,你可以简单地做mView.setOnClickListener(this);

这将自动设置代码中的所有视图对象使用onClick(view v)方法,您的片段或活动等。

为了区分哪个视图调用了onClick方法,你可以在v.getId()方法上使用switch语句。

这个答案不同于“不,通过代码是不可能的”

android:onClick是API级别4以上,所以如果你的目标< 1.6,那么你不能使用它。

   Add Button in xml and give onclick attribute name that is the name of Method.
   <!--xml --!>
   <Button
  android:id="@+id/btn_register"
  android:layout_margin="1dp"
  android:onClick="addNumber"
  android:text="Add"
  />


    Button btnAdd = (Button) findViewById(R.id.mybutton); btnAdd.setOnClickListener(new View.OnClickListener() {
   @Override
    public void onClick(View v) {
      addNumber(v);
    }
    });

  Private void addNumber(View v){
  //Logic implement 
    switch (v.getId()) {
    case R.id.btnAdd :
        break;
     default:
        break;
    }}

在Java 8中,您可以使用Method Reference来实现您想要的功能。

假设这是按钮的onClick事件处理程序。

private void onMyButtonClicked(View v) {
    if (v.getId() == R.id.myButton) {
        // Do something when myButton was clicked
    }
}

然后,像这样在setOnClickListener()调用中传递onMyButtonClicked实例方法引用。

Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(this::onMyButtonClicked);

这将允许您避免自己显式地定义匿名类。然而,我必须强调,Java 8的Method Reference实际上只是一个语法糖。它实际上为您创建了一个匿名类的实例(就像lambda表达式所做的那样),因此当您要取消事件处理程序的注册时,会应用lambda表达式风格的事件处理程序。这篇文章解释得很好。

PS.对于那些好奇我如何在Android中真正使用Java 8语言功能的人,这是retrolambda库的礼貌。