3

考慮以下情形:上方向正確留住聽衆改變

  1. 我有UI元素的Activity當點擊
  2. DialogFragment有聽衆interfaceActivity提供的實現,啓動一個DialogFragment。比方說,在Activity是一個圖像編輯器和DialogFragment選擇一個對比 - 對話將有一個OnContrastChangedListenerActivity實現
  3. Activity已執行了interface更新其UI意見。繼續圖像編輯器例如,Activity實現OnContrastChangedListener更新其預覽視圖 - 是這樣的:

    contrastDialog.setOnContrastChangedListener(new OnContrastChangedListener { 
        @Override 
        public void OnContrastChanged(int newContrast) { 
         getPreviewView().updateWithContrast(newContrast);    
        } 
    }); 
    
  4. 方向改變,一切都重新與聽者保存和恢復正確使用方法的建議here (偵聽器保存在Fragment中,並在生命週期恢復狀態時恢復)。

的問題是監聽器接口現在工作。該功能getPreviewView()現在返回null即使在Activity叫其他地方,當它返回正確的值

藉口窮人術語(我在編譯和字節碼是有限的知識),但我可以把握髮生了什麼事。該界面已編譯爲getPreviewView()版本,該版本返回在方向更改時被破壞的預覽視圖,並且此版本已被釋放/垃圾收集/現在爲null

我的問題是,是否有一種方法在Java中使界面編譯期望值/函數改變 - 很像C中的volatile關鍵字(我期待沒有)?在那種情況下,解決這種情況的最佳方法是什麼?我已經考慮了以下幾點:

  • 在當 Activity被重建是重新運行該代碼創建 DialogFragment(及其 interface)。對於 OnClickListenersButtons這是很好的,因爲它們是絕對創建的。但是,當按下按鈕這個 DialogFragment只被創建,所以這種方法意味着對於屏幕的每個對話框每次 Activity是在創建 - 這似乎浪費給予他們甚至可能不會運行
  • 創建所有可能 interfacesActivity,並將它們保存在成員變量中,然後在請求由事件創建 DialogFragments時使用這些 interfaces。以上評論與上面相同 - 看起來很浪費,創造每一個可能的 interface以防萬一它運行。
  • 在活動中保留一些hacky「打開對話框狀態」成員變量,指導interfaces的重新創建。 Hacky並在ActivityDialogFragment之間建立了聯繫,這不是很好的做法。

正如你所看到的,所有的選項都涉及娛樂,這在一定程度上是浪費的 - 有沒有辦法重用現有的interface實現?

編輯:選項1和2不會工作,因爲他們需要鏈接到現有Dialog。這一切都是可行的,但它越來越傾向於擁有'當前對話'變量的入侵選項,當活動重新啓動時獲得DialogFragmentFragmentManager,基於'當前對話'變量適當地轉換它,重新創建監聽器。有沒有一個混亂的方式?

+0

getPreviewView()實現在哪裏?你能告訴我們這種方法嗎? – 2014-10-04 04:32:50

+0

@ Code-Apprentice:這只是一個例子。對於這個例子,它的實現可以簡單地爲'return(PreviewView)findViewById(R.id.preview);''其中'PreviewView'是一個自定義視圖類,'R.id.preview'是XML佈局中定義的ID – 2014-10-04 05:19:22

回答

0

如果活動將始終具有接口的實現,是否可以在DialogFragment的onAttach()中設置偵聽器?這將確保當它被破壞並重新創建,它將擁有最先進的最新參考,如:

public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    contrastChangedListener = (OnContrastChangedListener)activity; 
} 

public void onDetach() { 
    super.onDetach(); 
    contrastChangedListener = null; 

} 
+0

這就是基本上只是選項2(這看起來像最好的可能性)。有幾個原因可以解決這個問題(將活動轉換爲監聽器:假設活動實現是一個糟糕的假設,如果另一個片段實現監聽器會發生什麼?) – 2014-10-04 05:28:07

1

onAttachonDetach方法是好的,我喜歡用它,有時,當我知道有將代碼中的我甚至不投它一味更多的開發者,但我做了檢查這樣的:

if(activity instanceof MyInterface){ 
    interface = (MyInterface) activity; 
} else{ 
    thrown new RuntimeException("Dear colleague, this fragment was meant to have the activity implementing MyInterface or else a bunch of other stuff won't work, please go back to your code and add the interface"); 
} 

但作爲一個不同的度假勝地,還可以重新設置界面時的片段重建。例如,在活動onCreate

if(savedInstanceState != null){ 
    mDialogFrag = getSupportFragmentManager().findFragmentByTag(MyDialogFrag.TAG); 
    if(mDialogFrag != null) 
     mDialogFrag.setListener(... the interface ...); 
} 

我知道,也沒有對象的最好的分離,但事實是,getPreviewView()需要當前的活動適當的操作,所以你需要的時候每個人都得到再通過這個參考毀壞重建。

這些只是做不同的方式。