一:基本使用
1界弧、顯示消息
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setMessage("message")
.setIcon(R.drawable.ic_info_black_24dp)
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel, null)
.show();
效果:2伟阔、顯示列表
CharSequence[] charSequence = new CharSequence[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setItems(charSequence, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//TODO
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
此時如果數(shù)據(jù)有更新怎么辦愈魏,我們就需要找到ListAlertDialog里面的ListView的Adapter觅玻,然后通知更新就可以了艇棕。
代碼可以像下面這么寫:
final CharSequence[] charSequence = new CharSequence[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final AlertDialog dialog = builder.setTitle("Title")
.setItems(charSequence, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//TODO
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
AsyncTask.execute(new Runnable() {
@Override
public void run() {
SystemClock.sleep(1500);
charSequence[1] = "BBBBB";
charSequence[2] = "ZZZZZ";
if (dialog.isShowing()) {
ListView listView = dialog.getListView();
final BaseAdapter adapter = (BaseAdapter) listView.getAdapter();
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
}
});
這里起一個線程模擬耗時任務,listView.getAdapter()獲得的對象為ListAdapter串塑,但是ListAdapter沒有notifyDataSetChanged()方法沼琉,查看源碼發(fā)現(xiàn)他使用的就是CheckedItemAdapter,而CheckedItemAdapter的父類就繼承自BaseAdapter桩匪,這里就強轉成BaseAdapter就可以了打瘪。
3、顯示單選和多選列表
顯示單選列表傻昙,類似RadioGroup闺骚。
CharSequence[] charSequence = new CharSequence[]{"A", "B", "C", "D", "E", "F", "G"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setSingleChoiceItems(charSequence, 1,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//TODO
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
顯示多選列表。
CharSequence[] charSequence = new CharSequence[]{"A", "B", "C", "D", "E", "F", "G"};
boolean[] booleans = new boolean[]{false, true, false, false, false, true, false};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setMultiChoiceItems(charSequence, booleans, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
4妆档、Cursor+列表
String[] projection = new String[]{
MediaStore.MediaColumns.TITLE,
MediaStore.MediaColumns._ID
};
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, null, null, null);
new AlertDialog.Builder(this)
.setTitle("Image Name")
.setMultiChoiceItems(cursor,
MediaStore.MediaColumns._ID,
MediaStore.MediaColumns.TITLE,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
5僻爽、自定義
1:setView設置內容區(qū)域,不包括Title和底部按鈕
View mContentView = LayoutInflater.from(this).inflate(R.layout.alert_dialog_editext, null);
new AlertDialog.Builder(this)
.setTitle("Input Name")
.setView(mContentView)
.setPositiveButton(android.R.string.ok, null)
.show();
2:setCustomTitle自定義標題贾惦,替換原有的Title和Icon所在的布局胸梆,所以此時setTitle和setIcon兩個方法的設置是無效的
View mTitleView = LayoutInflater.from(this).inflate(R.layout.title_view, null);
new AlertDialog.Builder(this)
.setMessage("This is Message")
.setCustomTitle(mTitleView)
.setPositiveButton(android.R.string.ok, null)
.show();
二:主題樣式
1、構造器
Builder有兩個構造器:
public Builder(Context context) {
this(context, resolveDialogTheme(context, ResourceId.ID_NULL));
}
public Builder(Context context, int themeResId) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, themeResId)));
}
只有一個參數(shù)的會生成一個默認的樣式給AlertDialog须板,這個樣式會跟隨Activity的主題碰镜;
第二個構造器需要自己傳入一個樣式。
2习瑰、修改樣式
1:Style控制樣式
<style name="DialogTheme" parent="ThemeOverlay.AppCompat.Dialog.Alert">
<item name="android:textColorPrimary">#FF00FF</item>
<item name="colorAccent">#00FFFF</item>
<item name="android:textSize">20sp</item>
</style>
textColorPrimary:設置Title和Message的顏色绪颖;
colorAccent:設置Button文字的顏色;
android:textSize:控制Button文字的大小甜奄。
new AlertDialog.Builder(this, R.style.DialogTheme)
.setMessage("This is Message")
.setTitle("Title")
.setPositiveButton(android.R.string.ok, null)
.show();
2:Message和Button的顏色動態(tài)修改
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setMessage("This is Message")
.setTitle("Title")
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel, null)
.show();
TextView msg = alertDialog.findViewById(android.R.id.message);
msg.setTextColor(0x80000000);
Button pBtn = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (pBtn != null) {
pBtn.setTextColor(getResources().getColor(R.color.colorAccent));
}
Button nBtn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
if (nBtn != null) {
nBtn.setTextColor(getResources().getColor(R.color.colorAccent));
}
android.R.id.message:Message所在TextView的ID柠横;
getButton(DialogInterface.BUTTON_POSITIVE):PositiveButton;
getButton(DialogInterface.BUTTON_NEGATIVE):NegativeButton课兄。
其中Title所在View的ID是android:id="@+id/alertTitle"牍氛,但是通過findViewById是找不到的。
3第喳、Material Design規(guī)范顏色和字號
Title text:顏色87%透明度的黑糜俗,字體android:fontFamily="sans-serif-medium",文字大小20sp曲饱;
Message text:顏色54%透明度的黑,字體android:fontFamily="sans-serif"珠月,文字大小16sp扩淀;
Button:顏色跟隨主題色,字體android:fontFamily="sans-serif-medium"啤挎,文字大小14sp驻谆;
三:問題Bug
1卵凑、華為android6.0/7.0/8.0等系統(tǒng)的手機開啟單手模式,Dialog展示的位置有問題胜臊,左右距離不等(貌似華為在android9.0修復了此問題)勺卢。
正常手機截圖:
2、條件:①象对、小米android9.0以上系統(tǒng)
②黑忱、開啟全屏模式
③、Dialog里面的內容的列表可以滾動
結果:Dialog展示時會跳動一下勒魔。
3甫煞、條件:①、Activity的主題里面包含<item name="android:windowTranslucentStatus">true</item>
②冠绢、Dialog里面的內容列表可以滾動
結果:Dialog展示時會跳動一下(不是所有手機都存在這個問題抚吠,而且如果使用的是Android API下的AlertDialog是不會出問題的)。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
String[] strings = new String[50];
for (int i = 0; i < strings.length; i++) {
strings[i] = i + "";
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setSingleChoiceItems(strings, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton(android.R.string.ok, null)
.show();
四:進階
1弟胀、dialog.dismiss();可以在子線程調用而不會崩潰楷力。
源碼:
@Override
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
2、在dialog的cancel()方法里面會調用dismiss()方法孵户,所以當調用cancel()方法時onCancel和onDismiss都接收到回調弥雹,而且順序是先回調給onCancel然后回調給onDismiss。
源碼:
@Override
public void cancel() {
if (!mCanceled && mCancelMessage != null) {
mCanceled = true;
// Obtain a new message so this dialog can be re-used
Message.obtain(mCancelMessage).sendToTarget();
}
dismiss();
}
3延届、可以通過給Dialog設置setOnKeyListener監(jiān)聽返回鍵的點擊剪勿。