运行时等效于(XML)android:onClick?
在Android 1.6版中实现按钮处理程序的一种方法是将其放入声明按钮的XML中运行时等效于(XML)android:onClick?,android,Android,在Android 1.6版中实现按钮处理程序的一种方法是将其放入声明按钮的XML中 ... android:onClick="TheButtonHandler" ... 然后将处理程序例程放入Activity类中 public void TheButtonHandler(View target) { // ... button handler code } 我有一些Android代码,其中所有按钮都是在初始化期间在运行时用Java创建的,不是用XML创建的,但我想做与上述XM
...
android:onClick="TheButtonHandler"
...
然后将处理程序例程放入Activity类中
public void TheButtonHandler(View target) {
// ... button handler code
}
我有一些Android代码,其中所有按钮都是在初始化期间在运行时用Java创建的,不是用XML创建的,但我想做与上述XML相同的事情,包括指定按钮处理程序N.B.我希望按钮处理程序位于各自独立的例程中,就像我在上面的示例中用XML声明它们一样,我不希望按钮处理程序代码嵌入到我的初始化代码中
我见过使用setOnClickListener的例子,但是处理程序代码总是内嵌的,例如
demoButton.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// ... button handler code
}});
。。。这就是我不想要它的地方,因为这会把按钮处理程序代码放在按钮初始化的地方。android:onClick的Java运行时等价物是什么?如果这是您所请求的,那么您不必将它们内联。 您可以创建自己的类,例如:
MyButtonClickListener implements Button.OnClickListener
{
...
}
这可以在其他地方定义。然后,您可以在初始化代码中类似地引用它,但不会占用那么多的可读性空间
demoButton.setOnClickListener(new MyButtonClickListener());
如果这确实是你的问题。方法1
public class YourActivity extends Activity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//....
myButton1.setOnClickListener(this);
myButton2.setOnClickListener(this);
myButton3.setOnClickListener(this);
myButton4.setOnClickListener(this);
myButton1.setTag(0);
myButton2.setTag(1);
myButton3.setTag(2);
myButton4.setTag(3);
}
@Override
public void onClick(View v) {
//Do your stuff
switch ((int) v.getTag()) {
case 0:
//First button pressed;
break;
case 1:
//Second button pressed;
break;
case 2:
//Third button pressed;
break;
case 3:
//Fourth button pressed;
break;
default:
//Unknown value, handle an error
break;
}
}
}
方法2
public class YourActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//....
myButton1.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// ... button handler code
}
});
myButton2.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// ... button handler code
}
});
myButton3.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// ... button handler code
}
});
myButton4.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// ... button handler code
}
});
}
}
等价物是
setOnClickListener()
和View.OnClickListener
如果您这样做,您将看到使用onClick
属性定义的方法被转换为OnClickListener
,该方法通过Java反射调用命名方法
我见过使用setOnClickListener的例子,但是处理程序代码总是内嵌在内联中。。。这就是我不想要它的地方,因为这会把按钮处理程序代码放在按钮初始化的地方
您可以将OnClickListener
s作为成员变量,例如:
private OnClickListener mClickListener = new OnClickListener() { ... };
//
view.setOnClickListener(mClickListener);
要在不同的位置进行初始化和单击处理。正如@laalto已经指出的,Android视图本身只需使用处理程序的名称,并使用Java反射创建OnClickListener对象。我从View.java中挖掘出代码,并将其包装在一个单独的对象中:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.view.View;
public class ViewOnClickHandler implements View.OnClickListener{
Activity mActivity;
Method mHandler;
ViewOnClickHandler(Activity activity, View view, String handlerName){
mActivity = activity;
try {
mHandler = activity.getClass().getMethod(handlerName, View.class);
} catch (NoSuchMethodException e) {
int id = view.getId();
String idText = id == View.NO_ID ? "" : " with id '"
+ mActivity.getResources().getResourceEntryName(id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ activity.getClass() + " for onClick handler"
+ " on view " + view.getClass() + idText, e);
}
}
@Override
public void onClick(View v) {
try {
mHandler.invoke(mActivity, v);
} 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);
}
}
static void set(Activity activity, View view, String handlerName){
view.setOnClickListener(new ViewOnClickHandler(activity, view, handlerName));
}
}
如果将此代码放入您选择的包中并将类导入到活动中,则示例中的代码可以缩减为:
ViewOnClickHandler.set(this, demoButton, "TheButtonHandler");
所有回合都将导致使用
View.setOnClickListener()
。。。我希望别无选择…@GopalRao你为什么希望它?谁投票赞成关闭这个,为什么?@blackbelt我没有理解你?对于动态创建的视图,除了View.setOnClickListener()
,android:onClick还有其他选择吗?没有,这些是唯一的选择。但为什么是“希望”@GopalRaoSure,但这仍然比android更加混乱和复杂:XML中的OnClick。所以我不会把它叫做等价物。XML中的大多数内容在Java中都有一个等价物。您可以在java和XML中的一行中设置颜色、文本或启用状态(etc等)。这会在一行中设置侦听器。即使在XML中进行设置,您仍然必须编写该方法。但是这为每个按钮处理程序实现了一个单独的类,对吗?在XML示例中,每个处理程序只有主活动类和单独的例程。所以我不明白这是如何“等价”的。我不确定我是否理解这一点。每个活动一个处理程序?在我的活动中,XML中有一个2x3的按钮网格(6个按钮),我可以在同一个活动中声明6个处理程序。所以我不确定这在什么意义上是等价的。你可以这样做,要么内联你的OnClickListener
,要么当你得到你的按钮时,你可以调用myButton.setTag((int)SomeId)
,然后在onClick中
在标签上运行开关
。我现在就用一个例子来更新我的帖子。好的,请看上面的代码以了解这两种方法的例子,也没有什么能阻止你内联你的onClick
,然后只调用MyHandlingFunction()在onClick
中的code>分隔逻辑。我很感激你在这方面所做的努力,所以我给了你一个+1,但我想你真正想说的是,没有什么能与我用XML得到的东西相媲美。标记方法是一种变通方法,它可以模拟在XML中进行标记的某些方面,但是增加了标记和案例代码的复杂性。是的,这是我能想到的最好的变通方法,但为了简单起见,我认为使用android:onClick
是最好的。也可以看到Iaalto的答案,这也是另一种方法,它保留了一个可读的方法引用(就像方法名一样),但我不会说它等同于XML。我相信你的话——我不会尝试阅读19K行的源代码——如果我们使用XML,平台可以免费发挥一系列神奇的作用,但如果我们使用java,平台就不会。因此,如果我们在java中这样做,我们必须添加我们自己的复杂性层——命名或匿名类、标记、case语句或其他。所以我的问题的答案是“不,没有等价物”。@user316117它实际上只有约40行代码,因为他链接到了合适的开关盒。值得一看他们是怎么做的。