0

我目前遇到了一個問題,我有一個叫做'PopupWindow'的超類,它初始化了一個AlertDialog.Builder並將其顯示給用戶。不過,我有兩個名爲'CallInitializePopup'和'CallReinitializePopup'的子類。我想將輸入監聽器(onClick)「外包」到這些子類中,並將代碼單獨分配給在那裏調用的子類。Android - OnClick在子類中的使用,而不是超級

片段PopupWindow的:

private void setInputListener() 
{ 
    Log.d("setInputListener", "called"); 

    alert.setPositiveButton("Set Alert", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      //Store the values in current variables 
      stockSymbol = stockSymbolEditText.getText().toString(); 
      stockPrice = stockPriceEditText.getText().toString(); 
      //String selectedInterval = updateIntervalSpinner.getSelectedItem().toString(); 
      buyOrSell = buySellSpinner.getSelectedItem().toString(); 

      Log.d("Alert dialog submitted", "stockSymbol: " + stockSymbol + " - " + "stockPrice: " + stockPrice + " - " + "buyOrSell: " + buyOrSell); 


      //Only call 'AssignStockCall()' once stockSymbol, stochPrice, and buyOrSell are initialized in the onClick method 
      //Create a new StockCall with the new info the user included 
      AssignNewStockCall(); 
     } 
    }); 

    //With 'setNegativeButton' we don't want to do anything, the user doesn't want to add a new stock call 
    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      //Canceled 
     } 
    }); 
} 

第一種方法不顯示任何按鈕,如果我是以此來猜測這就是:在一個子類

alert = new AlertDialog.Builder(mainActivity); 

    //'setTitle' simply sets the title of the popup 
    //'setMessage' sets the description, usually a short instruction on what the user should enter 
    alert.setTitle(POPUP_LOGIN_TITLE); 
    alert.setMessage(POPUP_LOGIN_TEXT); 

    //Initialize EditTexts that will populate our popup and set the hints for each 
    stockSymbolEditText = new EditText(mainActivity); 
    stockSymbolEditText.setHint(STOCK_SYMBOL_HINT); 
    stockPriceEditText = new EditText(mainActivity); 
    stockPriceEditText.setHint(STOCK_PRICE_HINT); 

    //These TextViews are only there to give the user guidance on what to include regarding the Spinners(since the Spinners doesn't include hints) 
    buyOrSellTextView = new TextView(mainActivity); 
    buyOrSellTextView.setText(" Alert - buy or sell"); 

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
    layoutParams.setMargins(0, 0, 0, 35); 

    LinearLayout layout = new LinearLayout(mainActivity); 
    layout.setOrientation(LinearLayout.VERTICAL); 
    layout.addView(stockSymbolEditText, layoutParams); 
    layout.addView(stockPriceEditText, layoutParams); 
    //layout.addView(updateIntervalTextView); 
    //layout.addView(updateIntervalSpinner); 
    layout.addView(buyOrSellTextView); 
    layout.addView(buySellSpinner); 
    alert.setView(layout); 

    //Finally we show the popup 
    alert.show(); 

我的第一個OnClickListener方法因爲我們在另一個類之後初始化inputListener,而不是初始化AlertDialog.Builder。

第二種方法:

//These onClick classes are used by the PopupWindow class, they are assigned to the specific button by supplying a new instance of the classes 
final class CancelOnClickListener implements 
     DialogInterface.OnClickListener 
{ 
    public void onClick(DialogInterface dialog, int which) 
    { 
     Log.d("onClick", "Cancel"); 
    } 
} 

final class SetAlertOnClickListener implements 
     DialogInterface.OnClickListener 
{ 
    public void onClick(DialogInterface dialog, int which) 
    { 
     Log.d("onClick", "Set Alert"); 
    } 
} 

這種做法不與超類的工作,因爲超類需要知道它是否是一個「CallInitializePopup」或「CallReinitializePopup」並沒有超級和子類之間的這種通信。

任何幫助,高度讚賞!

回答

1

如果您不改變自己的編碼風格,將來會遇到類似這樣的問題。首先你應該學習面向對象編程的SOLID原則。 https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29然後研究設計模式。 Derek Banas youtube頻道在幫助,因爲他非常清楚地解釋設計模式。 在你的情況下,你違反了開放封閉原則(來自SOLID原則)。超類不應該依賴於子類。 我不會在你的情況下使用繼承。如果您需要不同的執行相同的操作,請使用策略或狀態設計模式。

示例使用策略模式

class PopUpWindow implements DialogInterface.OnClickListener 
{ 
    /** 
    * 
    * 
    * other code 
    * 
    **/ 

    /** You don't need two different listers. Use same listener since 
     you can determine which button has been pressed from *int which* **/ 

    alert.setPositiveButton(this); 
    alert.setNegativeButton(this); 

    interface Strategy 
    { 
     public void doWork(); 
    } 

    @Override 
    public void onClick(DialogInterface dialog, int which) 
    { 
     switch(which) 
     { 
      case dialog.BUTTON_POSITIVE : 
        getPositiveButtonStrategy().doWork(); break; 
      case dialog.BUTTON_NEGATIVE : 
        getNegativeButtonStrategy().doWork(); break; 

     } 
    } 

    private Strategy getPositiveButtonStrategy() 
    { 
     if (/** conditions to implementation NO1**/) 
       return new Strategy 
         { 
          @Override 
          public void doWork() 
          { 
           /** your implementation NO1 **/ 
          } 
          } 
         else return new Strategy 
             { 
             @Override 
             public void doWork() 
             { 
              /** your implementation NO2 **/ 
             } 
             }; 
       /** you can implement as much Strategies as you need **/      
     } 
    } 

    private Strategy getNegativeButtonStrategy() 
    { 
     if (/** conditions to implementation NO1**/) 
       return new Strategy 
         { 
          @Override 
          public void doWork() 
          { 
           /** your implementation NO1 **/ 
          } 
          } 
         else return new Strategy 
             { 
             @Override 
             public void doWork() 
             { 
              /** your implementation NO2 **/ 
             } 
             }; 
       /** everything in your class is available for "Strategies" **/      
     } 
    } 
} 

不知道紮實的設計模式是接近不可能寫出可以理解的,可維護的,無缺陷的代碼

+0

感謝您的建議!我對OOP概念很陌生,我一定會看看Derek Banas的視頻。 –

相關問題