Android默认的AlertDialog太单调,我们可以通过继承原生的Dialog来实现自定义的Dialog。
本文的自定义Dialog和原生的AlertDialog的创建方式类似,通过一个静态Builder类来设置Dialog的图标、标题、内容和按钮。
如果想要在Dialog中使用输入框或者其他控件,方法也是类似的,只要写好布局再加载就可以了。
Github:https://github.com/imcloudfloating/DesignApp
效果:
布局文件代码:
(注意这里的根布局的宽高如果用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 }