2017-01-18 26 views
0

我发现人们经常使用一个处理多个事件源(对于几个按钮的exeampl一个OnClickHandler(视图v))。一个OnClickHandler与开关/案件与匿名内部类

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) { 
    mButton1 = (Button) v.findViewById(R.id.button1); 
    mButton2 = (Button) v.findViewById(R.id.button2); 
    mButton1.setOnClickListener(this); 
    mButton2.setOnClickListener(this); 
} 

@Override 
public boolean onClick(final View v) { 
    if (v == mButton1) { 
     title = getString(R.string.action1Title); 
     defaultText = getText1(); 
    } else if (v == mUriLabel) { 
     title = getString(R.string.action2Title); 
     defaultText = getText2; 
    } 

    // Here some common code 
} 

在这里,我们有两个功能:然后处理程序取决于参数v

一个分支,比如选择。 onCreateView只是将所有事件导向单个处理程序。而onClick是由它自己处理的,它应该确定事件的来源并且转到一个分支或另一个分支。

另一方面,我们可以在实现onClick的anonymouse内部类中实例化。就像这样:

// In cases, when there is some common part, 
// we need additional interface to separate common part and 
// customizable action. 
interface ICustomAction { 
    void doSomeAction(); 
} 

class BaseHandler implements View.ClickListener { 
    ICustomAction mCustomAction; 

    // Constructor which receive specific action 
    CommonHandler(ICustomAction customAction) { 
     mCustomAction = customAction; 
    } 

    @Override 
    public boolean onClick(final View v) { 
     mCustomAction.doSomeAction(); 
     // Here some common code 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) { 
    mButton1 = (Button) v.findViewById(R.id.button1); 
    mButton1.setOnClickListener(new BaseHandler(new ICustomAction() { 
     @Override 
     void doSomeAction() { 
      title = getString(R.string.action1Title); 
      defaultText = getText1(); 
     } 
    })); 

    mButton2 = (Button) v.findViewById(R.id.button2); 
    mButton2.setOnClickListener(new BaseHandler(new ICustomAction() { 
     @Override 
     void doSomeAction() { 
      title = getString(R.string.action2Title); 
      defaultText = getText2(); 
     } 
    })); 

在这里,我们有更复杂的通信类,但局部的附近注册处理的具体差异。我们用一个虚拟函数(定义在ICustomAction接口中)替换开关/外壳。

而且IDE可以简化表示这样的匿名类,并显示他们像拉姆达功能

mButton2.setOnClickListener(new BaseHandler(() ->{ 
      title = getString(R.string.action2Title); 
      defaultText = getText2(); 
     })); 

所以,登记处理变得更加紧凑,但还是老样子包含有意义的差异。

问题是,在switch/case statment中使用一个处理程序以及使用anonymouse内部类的方法更可取的原因是什么?

+0

如果您根据类似的实现进行比较,它会更有意义。例如。如果你已经使用了'mButton1.setOnClickListener(新的View.OnClickListener'而不是这个自制的'复杂'层次结构 –

+0

我想展示一些常见代码的例子,它总是执行直接继承'View.OnClickListener'导致代码重复在这种情况下 – Piroxiljin

回答

1

匿名内部类比switch case更可取。

考虑一种情况,如果布局中视图的数量更多,并且您已在onClick()方法中为所有视图设置开关盒,则您的开关盒必须进行几次比较才能达到正确的值。

如果只有两到三个视图在这种情况下不会产生很大的差异,则可以使用切换大小写,而不是对所有视图使用大量视图的匿名内部类。

如果您认为可读性将成为匿名内部类的问题。您可以创建一个setOnClickListeners()方法来将所有匿名内部类从onCreate方法中分离出来。感谢@Darwind获取有关可读性的说明。

+1

这是非常有见地的,真的取决于你的“个人”风格,认为多重比较可能是一个问题并没有真正增加任何价值,是的,它创造了更多的比较,但它也创造了一个入口点,如果你使用多个内部匿名类,你不一定知道该去哪里,并且必须查看代码,这在可读性方面也是一个问题。最后,我会倾向于可读性“性能” – Darwind

+0

@Darwind性能将在您的视图中包含多个onClick事件时起作用,例如:计算器。将所有匿名内部类抽象为一个名为setOnClickListeners()的单独方法,这将允许您以可读形式提供它。 –

+0

@Darwind,另一方面,基于匿名内部类的实现直接位于调用'setOnClickListener'的位置。有人可能会觉得它有意义而且很可读。但是我明白你的观点:它非常有见识,应该从可读性的角度考虑。感谢您的意见。 – Piroxiljin