2017-01-18 111 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