Android中Dialog與DialogFragment的對比

最近學習對話框時發現有兩種類型的可供使用,一種是Dialog,另外一種則是Android 3.0 引入的基於Fragment的DialogFragment。 java

從代碼的編寫角度看,Dialog使用起來要更爲簡單,可是Google則是推薦儘可能使用DialogFragment(對於Android 3.0如下的版本,能夠結合使用support包中提供的DialogFragment以及FragmentActivity)。今天試着用這兩種方式來建立對話框,發現DialogFragment果真有一個很是好的特性(在手機配置變化,致使Activity須要從新建立時,例如旋屏,基於DialogFragment的對話框將會由FragmentManager自動重建,然而基於Dialog實現的對話框則沒有這樣的能力)。 android

下面是兩段實例代碼: ide

他們使用的界面都同樣:(dialog.xml) 佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

1.基於Dialog實現的對話框 學習

public class MainActivity extends Activity {
	private Button clk;
	private Dialog dialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		clk = (Button) findViewById(R.id.clk);
		dialog = new Dialog(this);
		dialog.setContentView(R.layout.dialog);
		clk.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				dialog.show();
			}
		});
	}
}



當咱們點擊按鈕時,會彈出對話框(內容爲android logo),當咱們旋轉屏幕後,Activity從新建立,整個Activity的界面沒有問題,而對話框消失了。

除此以外,其實還有一個問題,就是在logcat中會看到異常信息:Android..leaked .. window,這是由於在Activity結束以前,Android要求全部的Dialog必需要關閉。咱們旋屏後,Activity會被重建,而上面的代碼邏輯並無考慮到對話框的狀態以及是否已關閉。 this

因而將上述代碼修改成: .net

public class MainActivity extends Activity {
	private Button clk;
	private Dialog dialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		clk = (Button) findViewById(R.id.clk);
		dialog = new Dialog(this);
		dialog.setContentView(R.layout.dialog);
		clk.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				dialog.show();
			}
		});

		//用戶恢復對話框的狀態
		if(savedInstanceState != null && savedInstanceState.getBoolean("dialog_show"))
			clk.performClick();
	}

	/**
	 * 用於保存對話框的狀態以便恢復
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if(dialog != null && dialog.isShowing())
			outState.putBoolean("dialog_show", true);
		else
			outState.putBoolean("dialog_show", false);
	}

	/**
	 * 在Activity銷燬以前,確保對話框以關閉
	 */
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if(dialog != null && dialog.isShowing())
			dialog.dismiss();
	}
}



2. 基於DialogFragment的對話框 code

與上面的對話框使用一樣的界面佈局,此處僅僅展示一個簡單對話框,所以只重寫了onCreateView方法 orm

public class MyDialogFragment extends DialogFragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.dialog, container, false);
		return v;
	}
}



public class MainActivity extends FragmentActivity {
	private Button clk;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		clk = (Button) findViewById(R.id.clk);
		clk.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				MyDialogFragment mdf = new MyDialogFragment();
				FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
				ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
				mdf.show(ft, "df");
			}
		});
	}
}



這兩段代碼能夠實現第一種方式的一樣功能,此處咱們並無去關心對話框的重建,以及Activity銷燬前對話框是否已關閉,這一切都是由FragmentManager來管理。

其實DialogFragment還擁有fragment的優勢,便可以在一個Activity內部實現回退(由於FragmentManager會管理一個回退棧) xml


關於Fragment的常見問題,能夠參見: Android Fragment 常見問題及解決方案

相關文章
相關標籤/搜索