Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
运行时等效于(XML)android:onClick?_Android - Fatal编程技术网

运行时等效于(XML)android:onClick?

运行时等效于(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 1.6版中实现按钮处理程序的一种方法是将其放入声明按钮的XML中

...
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行代码,因为他链接到了合适的开关盒。值得一看他们是怎么做的。