从我读过,您可以通过onClick两种方式为按钮分配处理程序.
使用android:onClickXML属性,您只需使用带有签名的公共方法的名称,void name(View v)或使用setOnClickListener传递实现OnClickListener接口的对象的方法.后者通常需要一个我个人不喜欢的匿名课程(个人品味)或者定义实现该课程的内部课程OnClickListener.
通过使用XML属性,您只需要定义一个方法而不是一个类,所以我想知道是否可以通过代码而不是XML布局来完成相同的操作.
Oct*_*ean 583
不,这不可能通过代码.Android只是OnClickListener在您定义android:onClick="someMethod"属性时为您实现.
这两个代码片段是相同的,只是以两种不同的方式实现.
代码实现
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
}
Run Code Online (Sandbox Code Playgroud)
以上是一个代码实现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 -->
Run Code Online (Sandbox Code Playgroud)
在后台,Android只执行Java代码,在单击事件上调用您的方法.
请注意,使用上面的XML,Android将仅在当前的Activity中查找该onClick方法myFancyMethod().如果您正在使用片段,这一点很重要,因为即使您使用片段添加上面的XML,Android也不会onClick在.java用于添加XML的片段文件中查找该方法.
我注意到的另一件重要事情 你提到你不喜欢匿名方法.你的意思是说你不喜欢匿名课程.
jp0*_*121 86
当我看到最顶层的答案时,它让我意识到我的问题不是将参数(View v)放在花哨的方法上:
public void myFancyMethod(View v) {}
Run Code Online (Sandbox Code Playgroud)
当试图从xml访问它时,应该使用
android:onClick="myFancyMethod"/>
Run Code Online (Sandbox Code Playgroud)
希望能帮助别人.
Man*_*ani 26
android:onClick在内部Button实例调用中指定属性结果setOnClickListener.因此绝对没有区别.
为了清楚地理解,让我们看看onClick框架如何处理XML 属性.
当布局文件膨胀时,其中指定的所有视图都将被实例化.在此特定情况下,Button使用public Button (Context context, AttributeSet attrs, int defStyle)构造函数创建实例.XML标记中的所有属性都从资源包中读取并传递AttributeSet给构造函数.
Buttonclass继承自View类,导致View调用构造函数,它负责设置单击回调处理程序setOnClickListener.
attrs.xml中定义的onClick属性在View.java中称为R.styleable.View_onClick.
以下代码View.java通过单独调用为您完成大部分工作setOnClickListener.
case R.styleable.View_onClick:
if (context.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new OnClickListener() {
private Method mHandler;
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = getId();
String idText = id == NO_ID ? "" : " with id '"
+ getContext().getResources().getResourceEntryName(
id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ getContext().getClass() + " for onClick handler"
+ " on view " + View.this.getClass() + idText, e);
}
}
try {
mHandler.invoke(getContext(), View.this);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not execute non "
+ "public method of the activity", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Could not execute "
+ "method of the activity", e);
}
}
});
}
break;
Run Code Online (Sandbox Code Playgroud)
如您所见,setOnClickListener调用注册回调,就像我们在代码中一样.唯一的区别是它用于Java Reflection调用我们的Activity中定义的回调方法.
以下是其他答案中提到的问题的原因:
Java Class getMethod使用以来,只搜索具有公共访问说明符的函数.否则准备处理IllegalAccessException异常.getContext().getClass().getMethod()call将方法搜索限制为当前上下文,在Fragment的情况下为Activity.因此,在Activity类中搜索方法而不是Fragment类.Java Class getMethod搜索接受View.class为参数的方法.Ant*_*zée 14
请注意,如果要使用onClick XML功能,则相应的方法应该有一个参数,其类型应与XML对象匹配.
例如,一个按钮将通过其名称字符串链接到您的方法:android:onClick="MyFancyMethod"但方法声明应显示:
...MyFancyMethod(View v) {...
如果您尝试将此功能添加到菜单项,它将在XML文件中具有完全相同的语法,但您的方法将声明为:...MyFancyMethod(MenuItem mi) {...
通过使用 XML 属性,您只需要定义一个方法而不是一个类,所以我想知道是否可以通过代码而不是在 XML 布局中完成相同的操作。
是的,您可以制作fragment或activity实施View.OnClickListener
当你在代码中初始化你的新视图对象时,你可以简单地做 mView.setOnClickListener(this);
这会自动将代码中的所有视图对象设置为使用onClick(View v)您fragment或其他人activity拥有的方法。
要区分哪个视图调用了该onClick方法,可以在该v.getId()方法上使用 switch 语句。
这个答案与说“不,这不可能通过代码实现”的答案不同
使用 Java 8,您可能可以使用方法引用来实现您想要的。
假设这是onClick按钮的事件处理程序。
private void onMyButtonClicked(View v) {
if (v.getId() == R.id.myButton) {
// Do something when myButton was clicked
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您onMyButtonClicked在这样的setOnClickListener()调用中传递实例方法引用 。
Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(this::onMyButtonClicked);
Run Code Online (Sandbox Code Playgroud)
这将允许您避免自己显式定义匿名类。然而我必须强调,Java 8 的方法引用实际上只是一个语法糖。它实际上为您创建了一个匿名类的实例(就像 lambda 表达式所做的那样),因此当您取消注册事件处理程序时,应用了与 lambda 表达式样式的事件处理程序类似的警告。这篇文章解释得非常好。
附注。对于那些对如何在 Android 中真正使用 Java 8 语言功能感到好奇的人,这是由retrolambda库提供的。
设置点击监听器的另一种方法是使用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"/>
Run Code Online (Sandbox Code Playgroud)
Java部分
public void showToast(View v) {
//Add some logic
}
Run Code Online (Sandbox Code Playgroud)
匿名Java类别/ setOnClickListener
XML部分
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)
Java部分
findViewById(R.id.button1).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
//Add some logic
}
});
Run Code Online (Sandbox Code Playgroud)
与匿名Java类相比,使用XML属性的好处如下:
当然,并非总是可以使用Xml属性,这是为什么我们不选择它的原因:
| 归档时间: |
|
| 查看次数: |
373983 次 |
| 最近记录: |