Dialog 筆記

  • AlertDialog 實現(xiàn)
  • 從屏幕底部彈出對話框
  • 自定義效果
  • Activity 仿 Dialog 效果

部分參考 android 底部彈出提示框的實現(xiàn)方式

基礎(chǔ)方法

構(gòu)造方法
很好幾個览露,要特別說的是這里的第二個养匈,可以加載一個 style 勒叠,
是實現(xiàn) dialog 寬度全屏的關(guān)鍵

Dialog(@NonNull Context context)
Dialog(@NonNull Context context, @StyleRes int themeResId) 

設(shè)置寬高
也可以直接使用數(shù)值

Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//設(shè)置 dialog 的寬高

設(shè)置動畫
style 文件朝抖,下面會介紹
window.setWindowAnimations(R.style.dialog_anim);//設(shè)置動畫效果

其他的方法

setTitle(@Nullable CharSequence title) //使用默認的標題
setCustomTitle(@Nullable View customTitleView) //傳入一個布局挎峦,自定義樣式
setIcon(@Nullable Drawable icon) //使用圖標做標題
setMessage(@Nullable CharSequence message) // 在標題下按鈕上的說明文字
setPositiveButton(CharSequence text, final OnClickListener listener) // 常用于"確定"按鈕
setNegativeButton(CharSequence text, final OnClickListener listener) //常用于"取消"按鈕
setCancelable(boolean cancelable) // 設(shè)置點擊框外是否可以關(guān)閉,默認為可以
setItems(CharSequence[] items, final OnClickListener listener) //用這個實現(xiàn)簡單的列表
setView(View view) //實現(xiàn)自定義的一個布局

監(jiān)聽事件


setOnCancelListener(OnCancelListener onCancelListener) 
setOnDismissListener(OnDismissListener onDismissListener)
setOnKeyListener(OnKeyListener onKeyListener)

AlertDialog 基礎(chǔ)實現(xiàn)

一個不怎么標準的例子:
因為例子中是在 Fragment 中缺亮,通過 LayoutInflater 獲取布局澈侠。
調(diào)用這個 openDialog() 方法即彈出對話框。

private void openDialog() {
    LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.change_password_dialog, null);
    final EditText originPasswordEt = (EditText) linearLayout.findViewById(R.id.origin_password);
    TextView forgetPassword = (TextView) linearLayout.findViewById(R.id.forget_password);
    final AlertDialog dialog = new AlertDialog.Builder(getContext())
        .setTitle("輸入密碼")
        .setView(linearLayout)
        .setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String originPassword = originPasswordEt.getText().toString().trim();
                //傳到后臺
            }
        })
        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        })
        .create();

    dialog.show();
    forgetPassword.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showToast("忘記密碼");
            dialog.dismiss();
        }
    });
}

布局文件:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <LinearLayout android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginStart="24dp"
                  android:orientation="horizontal">

        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/origin_password"
                  android:textColor="@color/black_primary_dark"
                  android:textSize="16sp"/>

        <EditText android:id="@+id/origin_password"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginEnd="16dp"
                  android:layout_marginStart="32dp"
                  android:hint="@string/origin_password_hint"
                  android:inputType="textPassword"
                  android:lines="1"/>
    </LinearLayout>

    <TextView android:id="@+id/forget_password" android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginBottom="8dp"
              android:layout_marginStart="24dp"
              android:layout_marginTop="16dp"
              android:text="@string/forget_password"
              android:textColor="@color/small_text_color"
              android:textSize="16sp"/>

</LinearLayout>

出現(xiàn)的位置铅辞,與相應動畫

彈出框出現(xiàn)在屏幕下方

Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);  //設(shè)置框的位置

彈出框會出現(xiàn)在屏幕下方藻治,但屏幕的左右和下方都有一個小的空隙

圖片源自[android 底部彈出提示框的實現(xiàn)方式](http://blog.csdn.net/wning1/article/details/51811513)

要使彈出框布不留有間隙,只改變布局的 layout_width 是不夠的巷挥,這個是主題 style 導致的
新建一個 style:

<style name="Dialog_Full">
     <item name="android:windowFullscreen">true</item>
     <!-- 背景透明 -->
     <item name="android:windowBackground">@android:color/transparent</item>
     <!-- activity變暗 -->
     <item name="android:backgroundDimEnabled">true</item>
        
</style>

并讓 dialog 引用這個 style

//在構(gòu)造函數(shù)中引用 style
AlertDialog dialog = new AlertDialog.Builder(getContext(),R.style.Dialog_Full).create();
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);

//設(shè)置橫向滿屏桩卵,縱向自適應,沒有這里彈出框會完全布滿屏幕
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT);

彈出的動畫和縮回的動畫

//pop_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="100%p"
        android:toYDelta="0" />
    <alpha
        android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
</set>

//pop_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromYDelta="0"
        android:toYDelta="100%p" />
</set>

還有一個 style:

<style name="dialog_anim" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/pop_in</item>
        <item name="android:windowExitAnimation">@anim/pop_out</item>
    </style>

設(shè)置引用這個 style:

Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setWindowAnimations(R.style.dialog_anim);//動畫效果
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT);
dialog.show();//show 必須在 set 后面

效果圖就不上了..

自定義效果

將這個控件封裝好利于復用倍宾,并且可以自定義不同數(shù)目的 item 而不需要重寫布局雏节。
依然是參考 android 底部彈出提示框的實現(xiàn)方式,添加了一些改動

  • 支持放任意多個 Item高职,但只有文字內(nèi)容
  • 選擇是否左右無間隙
  • 選擇是否有“取消”按鈕
  • 選擇是否可以點擊外部關(guān)閉
  • 文字居中或者靠左

核心代碼:



public static Dialog showItemSelectDialog() {
    final Dialog dialog;

    if (isFull){
        dialog = new Dialog(context,R.style.Dialog_Full);//傳入布局改變主題
    }else {
        dialog = new Dialog(context);
    }

    View rootView = LayoutInflater.from(context).inflate(R.layout.layout_choice,null);
    LinearLayout contentsView = (LinearLayout) rootView.findViewById(R.id.dialog_content);
    //逐個添加 TextView
    for(int i = 0;i < contents.length;i++){
        View centerView = LayoutInflater.from(context).inflate(R.layout.dialog_center_item,null);
        TextView centerText = (TextView)  centerView.findViewById(R.id.dialog_center_item);
        final int finali = i;
        centerText.setText(contents[finali]);
        centerText.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                if (listener != null){
                    listener.getSelectedItem(contents[finali]);
                }
            }
        });
        if (isTextCenter){
            centerText.setGravity(Gravity.CENTER);//水平和垂直居中
        }else{
            centerText.setPadding(20,0,0,0);
            centerText.setGravity(Gravity.CENTER_VERTICAL);//垂直居中
        }
        contentsView.addView(centerView);
    }
    Button CancleBtn = (Button) rootView.findViewById(R.id.dialog_cancel);

    if (isBtnCancle){
        CancleBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    }else {
        CancleBtn.setVisibility(View.GONE);
    }

    dialog.setContentView(rootView);

    if (isCancelable){
        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(true);
    }else {
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
    }

    Window window = dialog.getWindow();
    WindowManager.LayoutParams params = window.getAttributes();

    if (!(isCenter)){
        params.gravity = Gravity.BOTTOM;
    }
    params.width = WindowManager.LayoutParams.MATCH_PARENT;
    params.height = WindowManager.LayoutParams.WRAP_CONTENT;
    window.setAttributes(params);//設(shè)置 dialog 的寬高

    window.setWindowAnimations(R.style.dialog_anim);//設(shè)置動畫效果

    dialog.show();

    return dialog;
}

只是很粗糙的實現(xiàn)钩乍,很多可以改進的地方。
但如果再繼續(xù)折騰下去可能不還如直接用 popupwidow怔锌。

用 Activity 實現(xiàn)類似 Dialog 的效果

參考 Android中使用Dialog風格彈出框的Activity
在 style 新建:

<style name="dialogstyle">  
    <!--設(shè)置dialog的背景-->  
    <item name="android:windowBackground">@android:color/transparent</item>  
    <!--設(shè)置Dialog的windowFrame框為無-->  
    <item name="android:windowFrame">@null</item>  
    <!--設(shè)置無標題-->  
    <item name="android:windowNoTitle">true</item>  
    <!--是否浮現(xiàn)在activity之上-->  
    <item name="android:windowIsFloating">true</item>  
    <!--是否半透明-->  
    <item name="android:windowIsTranslucent">true</item>  
    <!--設(shè)置窗口內(nèi)容不覆蓋-->  
    <item name="android:windowContentOverlay">@null</item>  
    <!--設(shè)置動畫寥粹,在這里使用讓它繼承系統(tǒng)的Animation.Dialog-->  
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>  
    <!--背景是否模糊顯示-->  
    <item name="android:backgroundDimEnabled">true</item>  
</style>  

然后在 AndroidManifest.xml 中設(shè)置 DialogActivity 的 theme

來自 [Android 中使用 Dialog 風格彈出框的 Activity](http://blog.csdn.net/qq_20785431/article/details/50195977)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末变过,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涝涤,更是在濱河造成了極大的恐慌媚狰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阔拳,死亡現(xiàn)場離奇詭異崭孤,居然都是意外死亡,警方通過查閱死者的電腦和手機糊肠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門辨宠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人货裹,你說我怎么就攤上這事嗤形。” “怎么了弧圆?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵赋兵,是天一觀的道長。 經(jīng)常有香客問我墓阀,道長,這世上最難降的妖魔是什么拓轻? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任斯撮,我火速辦了婚禮,結(jié)果婚禮上扶叉,老公的妹妹穿的比我還像新娘勿锅。我一直安慰自己,他們只是感情好枣氧,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布溢十。 她就那樣靜靜地躺著,像睡著了一般达吞。 火紅的嫁衣襯著肌膚如雪张弛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天酪劫,我揣著相機與錄音吞鸭,去河邊找鬼。 笑死覆糟,一個胖子當著我的面吹牛刻剥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滩字,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼造虏,長吁一口氣:“原來是場噩夢啊……” “哼御吞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起漓藕,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤陶珠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后撵术,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體背率,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年嫩与,在試婚紗的時候發(fā)現(xiàn)自己被綠了寝姿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡划滋,死狀恐怖饵筑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情处坪,我是刑警寧澤根资,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站同窘,受9級特大地震影響玄帕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜想邦,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一裤纹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丧没,春花似錦鹰椒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夺饲,卻和暖如春奸汇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背往声。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工茫蛹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烁挟。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓婴洼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撼嗓。 傳聞我的和親對象是個殘疾皇子柬采,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容