android.support.v7.app.AlertDialog的使用

一:基本使用

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();

效果:
dialog.png

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();
list_dialog.png

此時如果數(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();

multi_chioce.png

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();
custom_view.png

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();
custom_view.png

二:主題樣式

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();
style.png

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ī)范顏色和字號

materil_design.png

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修復了此問題)勺卢。

問題手機截圖:
單手模式.png

正常手機截圖:
單手模式.png

2、條件:①象对、小米android9.0以上系統(tǒng)
②黑忱、開啟全屏模式
③、Dialog里面的內容的列表可以滾動
結果:Dialog展示時會跳動一下勒魔。


跳動.gif

正常.gif

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();
跳動.gif

四:進階

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)聽返回鍵的點擊剪勿。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市方庭,隨后出現(xiàn)的幾起案子厕吉,更是在濱河造成了極大的恐慌,老刑警劉巖械念,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件头朱,死亡現(xiàn)場離奇詭異,居然都是意外死亡龄减,警方通過查閱死者的電腦和手機项钮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來希停,“玉大人烁巫,你說我怎么就攤上這事〕枘埽” “怎么了亚隙?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長违崇。 經常有香客問我阿弃,道長诊霹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任渣淳,我火速辦了婚禮脾还,結果婚禮上,老公的妹妹穿的比我還像新娘入愧。我一直安慰自己鄙漏,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布砂客。 她就那樣靜靜地躺著泥张,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞠值。 梳的紋絲不亂的頭發(fā)上媚创,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音彤恶,去河邊找鬼钞钙。 笑死,一個胖子當著我的面吹牛声离,可吹牛的內容都是我干的芒炼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼术徊,長吁一口氣:“原來是場噩夢啊……” “哼本刽!你這毒婦竟也來了?” 一聲冷哼從身側響起赠涮,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤子寓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笋除,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斜友,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年垃它,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲜屏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡国拇,死狀恐怖洛史,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情贝奇,我是刑警寧澤虹菲,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掉瞳,受9級特大地震影響毕源,放射性物質發(fā)生泄漏。R本人自食惡果不足惜陕习,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一霎褐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧该镣,春花似錦冻璃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嫁审,卻和暖如春跋炕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背律适。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工辐烂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捂贿。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓纠修,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厂僧。 傳聞我的和親對象是個殘疾皇子扣草,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容