Android通用UI組件之Dialog

背景

Dialog是Android開發中經常使用的UI組件,爲了方便顯示對話框,系統提供了AlertDialog,它提供了豐富的API,使用時只須要設置相應的屬性便可。但一般狀況下,不會直接使用AlertDialog, 由於APP的設計並不必定都遵循Material Design的設計標準,同時這種通用的UI組件的設計風格也會常常發生變化。因此一般狀況下,都會對AlertDialog的樣式進行自定義,使其可以適用於各類設計風格。java

自定義Dialog

自定義Dialog一般使用如下三種方式:android

  • 經過AlertDialog提供的setView方法設置佈局;
  • 繼承AlertDialog, 在onCreate中調用setContentView加載佈局;
  • 繼承DialogFragment, 在onCreateView中加載佈局;

具體的核心代碼實現以下所示:git

// 方法一
View dialogView = View.inflate(this, R.layout.dialog_common_layout, null);
/**
 * 經過dialogView.findViewById獲取相應的View並設置對應的值
 */
new AlertDialog.Builder(this)
	.setView(dialogView)
	.show();


// 方法二
public class CommonDialog extends AlertDialog {

	public CommonDialog(Context context) {
		super(context);
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.dialog_common_layout);
		/**
		 * 經過findViewById獲取相應的View,設置對應的值
		 */
	}
}


// 方法三
public class CommonDialog extends DialogFragment {

	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
		View dialogView = inflater.inflate(R.layout.dialog_common_layout, null);
		/**
		 * 經過dialogView.findViewById獲取相應的View並設置對應的值
		 */
		return dialogView;
	}
}
複製代碼

第一種和第二種方法直接使用的Dialog類型, 這種方式Dialog的生命週期很差控制,容易出現WindowManager$BadTokenException異常。因此爲了Dialog的生命週期可以和Activity同步,推薦使用DialogFragment。可是在使用DialogFragment時,最好不要在onCreateView中直接加載佈局,由於這種方式至關於棄用了系統提供的AlertDialog樣式,若是APP要求使用系統提供的原生組件,此時修改起來可能就比較麻煩。其實DialogFragment還有一個重要的API——onCreateDialog,返回Dialog對象,因此可在裏面建立AlertDialog, 根據定義的樣式返回相應的風格。github

APP中使用Dialog的地方不少,但經常使用的也就那麼幾種:提示對話框,選擇對話框,底部彈框,加載框,爲了更好地進行風格切換,這裏同時支持了Material Design的設計風格(系統默認的樣式)和自定義的設計風格,只須要設置相應的風格便可。樣式以下圖所示,具體的源碼參考CommonDilaogide

image

修改Dialog默認樣式

在使用默認的對話框時,有時可能須要改變這幾個View的顏色,但AlertDialog並無提供直接的API進行設置,經過如下方法對其中的View進行設置。佈局

AlertDialog Title的樣式可經過設置Dialog主題中的windowTitle屬性實現:ui

<!-- Title的文字樣式 -->
<style name="AlertDialogTitleStyle">
    <item name="android:textSize">48dp</item>
    <item name="android:textColor">#ff0000</item>
    <item name="android:textStyle">bold</item>
</style>

<!-- Dialog的主題樣式 -->
<style name="CommonDialog" parent="Theme.AppCompat.Dialog">
    <!-- 引用定義的Title樣式 -->
    <item name="android:windowTitleStyle">@style/AlertDialogTitleStyle</item>
    <item name="android:windowBackground">@color/transparent</item>
</style>
複製代碼

其餘的View可經過系統id進行獲取:this

MessageViewId: android.R.id.message
PositiveButtonId: android.R.id.button1
NegativeButtonId: android.R.id.button2
複製代碼

先調用Dialog的show方法(由於調用show方法後Dialog纔開始加載佈局),而後獲取相應的View進行設置樣式,例如MessageView樣式的修改:spa

AlertDialog dialog = builder.show();
TextView messageText = dialog.findViewById(android.R.id.message);
messageText.setTextColor(Color.RED);
messageText.setTextSize(20);
複製代碼

Dialog主題

在自定義Dialog時,可能須要對Dialog所使用的主題進行定義,這裏介紹Dialog主題中經常使用的幾個屬性:設計

<style name="CommonDialog" parent="Theme.AppCompat.Dialog">
    <!-- 背景遮罩的不透明度,backgroundDimEnabled爲true時有效 -->
    <item name="android:backgroundDimAmount">0.4</item>
    <!-- 是否須要背景遮罩 -->
    <item name="android:backgroundDimEnabled">true</item>
    <!-- Dialog是否懸停 -->
    <item name="android:windowIsFloating">true</item>
    <!-- dialog的最小寬度佔總屏幕寬度的百分比 -->
    <item name="android:windowMinWidthMinor">85%</item>
    <!-- Dialog內容區域的背景 -->
    <item name="android:windowBackground">@color/transparent</item>
</style>
複製代碼

windowBackground屬性須要注意一下,若是Dialog的自定義佈局中設置了背景,那麼這裏可將其設置爲透明,不然在低版本的Android系統上會出現黑色邊框。若是自定義佈局中沒有設置背景,可將windowBackground屬性設置爲相應的Drawable資源。

固然,Dialog的主題中還有不少屬性。但沒有對齊相關的屬性。若是須要修改Dialog的對齊方式,可在show方法調用以後,獲取Dialog的LayoutParams參數進行相應的設置。例如讓Dialog顯示在底部:

WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.gravity = Gravity.BOTTOM;
dialog.getWindow().setAttributes(params);
複製代碼

總結

在對系統UI組件進行封裝時,必定要考慮原生的樣式,儘量利用系統提供的組件實現。這樣可在各類不一樣的UI風格之間進行切換。

相關文章
相關標籤/搜索