使用Listeners的正确方法是什么?

时间:2015-05-01 13:35:42

标签: java android android-event

我的老板说我写错了听众,并且不能提出任何好的论据。我通常这样做的方式是:

View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (R.id.basketCancel == view.getId()) {
                Observer.getInstance().send(MessageType.SCAN_STATUS, new ScanEvent(true));
                dismiss();
                return;
            }
        }
    };

 cancel.setOnClickListener(onClickListener );

他要求我这样写:

private class ClickButtonHandler implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        if (R.id.basketCancel == v.getId()) {
            Observer.getInstance().send(MessageType.SCAN_STATUS, new ScanEvent(true));
            dismiss();
            return;
        }
    }
}

private ClickButtonHandler clickButtonHandler = new ClickButtonHandler();
...
 cancel.setOnClickListener(clickButtonHandler);

我认为这会让事情复杂化。他相信所以我可以在任何地方实现多个侦听器来使用这个类的一个对象。但我通常只使用View.OnClickListener 而结构本身并不像我。我如何向他解释并证明我做得更好?或者你认为他是对的?我无法理解?

3 个答案:

答案 0 :(得分:1)

这个问题很难正确回答,因为在我看来,这是基于意见的。所以我将重点关注两种方法的优缺点:

如果您需要同一个实现的多个实例,则命名类是有意义的。您可以通过搜索重复的侦听器代码轻松识别这些位置。如果您的侦听器类保持任何状态,即具有一个或多个字段,则通常仅需要多个实例。 (如果它是无状态的(没有字段),只有一个实例就足够了。)

但是如果您需要某个侦听器实现一次,或者您可以重用某个侦听器实现的相同实例,那么您的方法(匿名内部类)似乎更适合我,因为它简化了你的代码。

答案 1 :(得分:1)

简短答案是:使用的方法取决于您的应用程序,即您可以从“快速”匿名内部侦听器开始,最终在命名类中重构它们(或者你的类直接实现接口)随着代码库的发展而变化。

回答:

从Java的角度来看,你基本上做了同样的事情:实例化匿名内部类(第一种方法)相当于声明一个内部命名类(第二种方法),然后实例化它。

唯一的区别是这个实例是一个局部变量(第一种方法)还是作为外部类字段保存,以便多次重复使用(第二种方法)。

第一种方法通常允许“更快”的编码,即在不编写完整声明的情况下实例化子类。
作为第一种方法的好处,您可以在匿名侦听器中读取 local [final]变量和封闭外部方法/块的参数,即:

    void outerClassMethod(final URL url, final String param, ... etc) {
            final int outerInt = updateMaxCount(...);

            // you have access to url, param, outerInt in your anonymous instance :
            View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (url.getHost().equals(...)) {// <- access url param here 
                        int local = outerInt * 2; //<- access outer method's outerInt
                    }

                }
            };
    }

但是,如果您发现多个匿名侦听器使用相同的代码,您应该考虑将公共代码放在命名类中并重用它(第二种方法)。

编辑 :关于第二种方法,请注意情况可能需要传递不同的侦听器对象,即使您声明内部类{{ 1}},即你可能需要:

ClickButtonHandler

否则,我宁愿让主类直接实现OnClickListener ,而不是内部类,即:

button1.setOnClickListener(new ClickButtonHandler());
...
//  and somewhere else
button2.setOnClickListener(new ClickButtonHandler());

希望有所帮助。

答案 2 :(得分:0)

您可以拥有包含多个按钮或可点击区域的视图。在这种情况下,只使用一个OnClickListener并对视图的id执行切换会更轻

myOnClickListener = new OnClickListener(){
    public void onClick(View view){
        if(view.getId() == view1.getId()){
            ...
        }else if(view.getId() == view2.getId()){
            ...
        }
    }
}
view1.setOnClickListener(myOnClickListener);
view2.setOnClickListener(myOnClickListener);