一个带有switch / case的OnClickHandler与匿名内部类

时间:2017-01-18 15:02:11

标签: java android onclicklistener theory

我发现人们常常为多个事件源使用一个处理程序(对于几个按钮,对于exeampl一个OnClickHandler(View v))。然后处理程序根据参数v

选择一个分支

例如:

@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
}

这里我们有两个功能。 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接口中定义)替换switch / case。

IDE也可以简化这种匿名类的表示,并像lambda函数一样显示它们

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

因此,注册处理程序变得更紧凑,但stil包含有意义的差异。

问题是,使用一个带有switch / case语句的处理程序的原因是什么,以及何时使用anonymouse内部类的方法更可取?

1 个答案:

答案 0 :(得分:1)

匿名内部类比切换案例更可取。

考虑一种情况,当你的布局中有更多的视图并且你在onClick()方法中为所有视图设置了switch case时,你的switch case必须做几次比较才能达到正确的值。

当只有两到三个视图在这种情况下不会产生很大的不同时,如果你有很多视图对所有视图使用匿名内部类,你可以使用switch case。

如果您认为可读性会成为匿名内部类的问题。您可以创建 setOnClickListeners()方法,以将所有匿名内部类与onCreate方法分开。感谢@Darwind获得关于可读性的说明。