Dialog除了使用Dialog類來實現之外,還可以使用Dialog樣式的Activity來實現,只需要在注冊Activity時指明theme為adnroid:Theme.Dialog就行,這樣的Dialog因為實際上是個Activity而更加豐富靈活。在API11(如果沒記錯的話)之前的dialog樣式Activity是模式的,點擊對話框外部對話框不會消失,而API11之后雖然依然是模式的,但點擊對話框外部后對話框消失,相當於點擊了返回鍵。
如何人為控制點擊對話框(Activity)外部時窗口是否銷毀呢?在API11之后添加了setFinishOnTouchOutside()方法,只需要在onCreate()方法中調用:
this.setFinishOnTouchOutside(false);
就可以設置點擊對話框外部是否消失,但API11之前沒有這個方法,也就是說API11之前沒有現成的方法能夠實現點擊dialog樣式Activity外部對話框消失,所以真正監聽這個點擊事件才是根本解決方法。
Stackoverflow上有人給出了一種非常有效的思路。首先在View創建之前設置兩個Flag,一個設置窗口為非模式的,這樣除窗口外的內容就可以獲得touch事件,然后設置窗口外部touch事件發生時的通知。最后重寫onTouchEvent,監聽窗口外的Touch事件。這樣就可以在監聽方法中自定義窗口外點擊事件的響應,是否關閉窗口或者其他操作。
public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Make us non-modal, so that others can receive touch events. getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL); // ...but notify us that it happened. getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); // Note that flag changes must happen *before* the content view is set. setContentView(R.layout.my_dialog_view); } @Override public boolean onTouchEvent(MotionEvent event) { // If we've received a touch notification that the user has touched // outside the app, finish the activity. if (MotionEvent.ACTION_OUTSIDE == event.getAction()) { finish(); return true; } // Delegate everything else to Activity. return super.onTouchEvent(event); } }
