假設有一個activity,activity中有一個Button和一個TextView,點擊按鈕,彈出Dialog,對話框中有一個ListView,選中ListView中的某一項,關閉對話框,更新activity中EditText的值為你選中項的值。
分析這個問題,假設Dialog為AlertDialog,你可以直接在Button的OnClickListener事件中創建Dialog,並在AlertDialog的setPositiveButton或其他按鈕監聽器中完成對EditText值的更新;如果Dialog為自定義Dialog,你也完全可以將這個自定義Dialog以Activity內部類的方式實現,這樣在Dialog中ListView的選擇事件監聽器中你仍然可以訪問到EditText。
但是我不喜歡以這樣的方式來實現,不管是代碼復雜度的原因還是耦合的原因,總之我還是喜歡將自定義Dialog使用單獨的類來創建。這樣的話,在Dialog中你就訪問不到Activity的EditText了,除非你將EditText的設為public(這當然不是一個好方法)。 網上查了下,發現可以通過回調函數來實現,仍然使用上一篇文章當中用到的自定義對話框作為例子,具體步驟如下:
1.新建一個接口作為Dialog的監聽器,並在接口中聲明回調函數:
/** * 自定義Dialog監聽器 * @author Kael.Chen * */ public interface PriorityListener { /** * 回調函數,用於在Dialog的監聽事件觸發后刷新Activity的UI顯示 */ public void refreshPriorityUI(); }
2、為自定義Dialog增加帶監聽器參數的構造函數:
private PriorityListener listener; public PriorityDlg(Context context) { super(context); this.context = context; // TODO Auto-generated constructor stub } public PriorityDlg(Context context, int theme) { super(context, theme); this.context = context; } public PriorityDlg(Context context, int theme, PriorityListener listener) { this(context, theme); this.listener = listener; }
3、在Dialog中需要的地方去調用回調函數,比如在ListView的選擇事件觸發時:
dlg_priority_lvw.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { dismiss(); listener.refreshPriorityUI(); } });
4、然后你在Activity中使用帶監聽器參數的構造函數去實例化自定義Dialog,並實現監聽器中聲明的回調函數就可以了:
//為優先級選擇按鈕增加監聽器 task_simple_form_priority.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //彈出任務優先級選擇對話框 PriorityDlg dlg = new PriorityDlg(SimpleTaskActivity.this, R.style.dlg_priority, new PriorityDlg.PriorityListener() { @Override public void refreshPriorityUI() { //這里就是用來刷新Activity的UI顯示的,如果你需要用到從Dialog傳回的數據,你可以把該數據存儲在全局變量中或者作為回調函數的參數傳遞進來 Toast.makeText(SimpleTaskActivity.this, "完成選擇", Toast.LENGTH_SHORT).show(); } }); dlg.show(); } });
解析(創建自定義對話框):
PriorityDlg dlg = new PriorityDlg(SimpleTaskActivity.this, R.style.dlg_priority); return dlg;
R.style.dlg_priority設置了對話框使用的樣式文件,只是讓對話框去掉標題欄,當然你也可以通過代碼來完成這種效果:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 對話框樣式 -->
<style name="dlg_priority" parent="@android:Theme.Dialog">
<item name="android:windowNoTitle">true</item>
</style>
</resources>