Android 自定义AlertDialog的实现
程序员文章站
2022-04-15 10:50:19
Android默认的AlertDialog太单调,我们可以通过继承原生的Dialog来实现自定义的Dialog。 本文的自定义Dialog和原生的AlertDialog的创建方式类似,通过一个静态Builder类来设置Dialog的图标、标题、内容和按钮。 如果想要在Dialog中使用输入框或者其他 ......
android默认的alertdialog太单调,我们可以通过继承原生的dialog来实现自定义的dialog。
本文的自定义dialog和原生的alertdialog的创建方式类似,通过一个静态builder类来设置dialog的图标、标题、内容和按钮。
如果想要在dialog中使用输入框或者其他控件,方法也是类似的,只要写好布局再加载就可以了。
效果:
布局文件代码:
(注意这里的根布局的宽高如果用match_parent或者设置为具体的数值都和wrap_conten效果一样,可以通过设置子控件的大小来撑开)
1 <?xml version="1.0" encoding="utf-8"?> 2 <android.support.constraint.constraintlayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="wrap_content" 7 android:layout_height="wrap_content" 8 android:background="#ffffff"> 9 10 <linearlayout 11 android:id="@+id/dialog_header" 12 android:orientation="vertical" 13 android:layout_width="220dp" 14 android:layout_height="wrap_content" 15 android:padding="16dp" 16 android:gravity="center" 17 android:background="@color/colorgreen" 18 app:layout_constrainttop_totopof="parent" 19 app:layout_constraintstart_tostartof="parent" 20 app:layout_constraintend_toendof="parent"> 21 22 <!-- icon --> 23 <imageview 24 android:contentdescription="@id/dialog_title" 25 android:id="@+id/dialog_icon" 26 android:layout_width="100dp" 27 android:layout_height="100dp" 28 android:src="@drawable/ic_check_circle" /> 29 30 <!-- title(default is gone) --> 31 <textview 32 android:id="@+id/dialog_title" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:padding="8dp" 36 android:textsize="18sp" 37 android:textstyle="bold" 38 android:textcolor="#ffffff" 39 android:visibility="gone" /> 40 41 </linearlayout> 42 43 <linearlayout 44 android:orientation="vertical" 45 android:layout_width="wrap_content" 46 android:layout_height="wrap_content" 47 android:padding="16dp" 48 android:gravity="center" 49 app:layout_constrainttop_tobottomof="@+id/dialog_header" 50 app:layout_constraintstart_tostartof="parent" 51 app:layout_constraintend_toendof="parent" 52 app:layout_constraintbottom_tobottomof="parent"> 53 54 <!-- dialog message --> 55 <textview 56 android:id="@+id/dialog_message" 57 android:layout_width="wrap_content" 58 android:layout_height="wrap_content" 59 android:padding="8dp" 60 tools:text="dialog message" /> 61 62 <button 63 android:id="@+id/dialog_button" 64 android:layout_width="100dp" 65 android:layout_height="42dp" 66 android:layout_margintop="16dp" 67 android:layout_marginbottom="8dp" 68 android:background="@drawable/bg_dialog_button" 69 android:textcolor="#ffffff" 70 android:text="@string/dialog_button"> 71 72 </button> 73 74 </linearlayout> 75 76 </android.support.constraint.constraintlayout>
infodialog类:
1 package com.cloud.design.dialog; 2 3 import android.app.dialog; 4 import android.content.context; 5 import android.graphics.bitmap; 6 import android.support.annotation.nonnull; 7 import android.view.layoutinflater; 8 import android.view.view; 9 import android.view.viewgroup; 10 import android.widget.button; 11 import android.widget.imageview; 12 import android.widget.textview; 13 14 import com.cloud.design.r; 15 16 public class infodialog extends dialog { 17 18 private infodialog(context context, int themeresid) { 19 super(context, themeresid); 20 } 21 22 public static class builder { 23 24 private view mlayout; 25 26 private imageview micon; 27 private textview mtitle; 28 private textview mmessage; 29 private button mbutton; 30 31 private view.onclicklistener mbuttonclicklistener; 32 33 private infodialog mdialog; 34 35 public builder(context context) { 36 mdialog = new infodialog(context, r.style.theme_appcompat_dialog); 37 layoutinflater inflater = 38 (layoutinflater) context.getsystemservice(context.layout_inflater_service); 39 //加载布局文件 40 mlayout = inflater.inflate(r.layout.dialog, null, false); 41 //添加布局文件到 dialog 42 mdialog.addcontentview(mlayout, new viewgroup.layoutparams(viewgroup.layoutparams.match_parent, 43 viewgroup.layoutparams.wrap_content)); 44 45 micon = mlayout.findviewbyid(r.id.dialog_icon); 46 mtitle = mlayout.findviewbyid(r.id.dialog_title); 47 mmessage = mlayout.findviewbyid(r.id.dialog_message); 48 mbutton = mlayout.findviewbyid(r.id.dialog_button); 49 } 50 51 /** 52 * 通过 id 设置 dialog 图标 53 */ 54 public builder seticon(int resid) { 55 micon.setimageresource(resid); 56 return this; 57 } 58 59 /** 60 * 用 bitmap 作为 dialog 图标 61 */ 62 public builder seticon(bitmap bitmap) { 63 micon.setimagebitmap(bitmap); 64 return this; 65 } 66 67 /** 68 * 设置 dialog 标题 69 */ 70 public builder settitle(@nonnull string title) { 71 mtitle.settext(title); 72 mtitle.setvisibility(view.visible); 73 return this; 74 } 75 76 /** 77 * 设置 message 78 */ 79 public builder setmessage(@nonnull string message) { 80 mmessage.settext(message); 81 return this; 82 } 83 84 /** 85 * 设置按钮文字和监听 86 */ 87 public builder setbutton(@nonnull string text, view.onclicklistener listener) { 88 mbutton.settext(text); 89 mbuttonclicklistener = listener; 90 return this; 91 } 92 93 public infodialog create() { 94 mbutton.setonclicklistener(view -> { 95 mdialog.dismiss(); 96 mbuttonclicklistener.onclick(view); 97 }); 98 mdialog.setcontentview(mlayout); 99 mdialog.setcancelable(true); //用户可以点击后退键关闭 dialog 100 mdialog.setcanceledontouchoutside(false); //用户不可以点击外部来关闭 dialog 101 return mdialog; 102 } 103 } 104 }
弹出:
1 public class mainactivity extends appcompatactivity { 2 3 @override 4 protected void oncreate(bundle savedinstancestate) { 5 super.oncreate(savedinstancestate); 6 setcontentview(r.layout.activity_main); 7 8 findviewbyid(r.id.button_show_dialog).setonclicklistener(v -> { 9 infodialog infodialog = new infodialog.builder(this) 10 .settitle("done") 11 .setmessage("something done") 12 .setbutton("ok", view -> 13 toast.maketext(this, "ok clicked.", toast.length_short).show() 14 ).create(); 15 infodialog.show(); 16 }); 17 } 18 }