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 }