版權聲明:本文為HaiyuKing原創文章,轉載請注明出處!
前言
對確認取消對話框的封裝。
前提:調用對話框的Activity必須繼承FragmentActivity及其子類(比如AppCompatActivity)。
效果圖
代碼分析
ConfirmCancelDialog繼承DialogFragment;
默認展現左側、中間、右側三個按鈕,通過DialogSetListener控制按鈕的隱藏【比如,如果想要展現一個按鈕,那么需要手動將其他兩個按鈕隱藏】;
通過DialogClickListener實現左側、中間、右側三個按鈕的監聽事件。
實現了點擊空白區域隱藏對話框的功能。
使用步驟
一、項目組織結構圖
注意事項:
1、導入類文件后需要change包名以及重新import R文件路徑
2、Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),如果項目中存在,則復制里面的內容,不要整個覆蓋
二、導入步驟
將ConfirmCancelDialog.java文件復制到項目中

package com.why.project.confirmcanceldialogdemo.dialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.content.ContextCompat; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.TextView; import com.why.project.confirmcanceldialogdemo.R; /** * Used 確認取消對話框樣式【含有標題、左中右三個按鈕(同時適用於兩個按鈕、一個按鈕)】 */ public class ConfirmCancelDialog extends DialogFragment{ private static final String TAG = ConfirmCancelDialog.class.getSimpleName(); private Context mContext; /**View實例*/ private View myView; /**標記:用來代表是從哪個界面打開的這個對話框*/ private String mTag; private boolean locked;//點擊空白區域是否隱藏對話框 /**設置對話框內容和樣式的監聽器(標題、內容、按鈕樣式,包括控制隱藏)*/ private DialogSetListener mDialogSetListener; /**三個按鈕的點擊事件監聽器*/ private DialogClickListener mDialogClickListener; public static ConfirmCancelDialog getInstance(Context mContext, DialogSetListener mDialogSetListener){ return getInstance(mContext,false,mDialogSetListener); } public static ConfirmCancelDialog getInstance(Context mContext, boolean locked, DialogSetListener mDialogSetListener){ ConfirmCancelDialog dialog = new ConfirmCancelDialog(); dialog.mContext = mContext; dialog.locked = locked; dialog.mDialogSetListener = mDialogSetListener; return dialog; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0));//設置背景為透明,並且沒有標題 //getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#80000000")));//設置背景為半透明,並且沒有標題 getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉標題欄 myView = inflater.inflate(R.layout.dialog_confirm_cancel, container, false); if(locked) { this.getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; // return true是中斷事件,那么下面的就接受不到按鍵信息了 } else { return false; //在return false的時候 才會事件繼續向下傳遞。 } } }); } return myView; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); //初始化控件以及設置初始數據和監聽事件 initView(); } /** * 設置寬度和高度值,以及打開的動畫效果 */ @Override public void onStart() { super.onStart(); //設置對話框的寬高,必須在onStart中 DisplayMetrics metrics = new DisplayMetrics(); this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); Window window = this.getDialog().getWindow(); if(locked){ window.setLayout(metrics.widthPixels, metrics.heightPixels - getStatusBarHeight(mContext));//這樣可以實現點擊空白區域無法隱藏對話框的功能 }else { window.setLayout(metrics.widthPixels, this.getDialog().getWindow().getAttributes().height);//這樣才能實現點擊空白區域自動隱藏對話框 } window.setGravity(Gravity.CENTER);//設置在中間 //打開的動畫效果--縮放+漸隱 } /**獲取狀態欄的高度*/ private int getStatusBarHeight(Context context) { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); //根據需要執行 if(mDialogClickListener != null){ mDialogClickListener.onDismissListener(); } } /**實例化控件*/ @SuppressWarnings("deprecation") private void initView() { TextView title = (TextView)myView.findViewById(R.id.title);//標題 TextView titleDelever = (TextView)myView.findViewById(R.id.delever_up_message);//標題下划線 TextView message = (TextView)myView.findViewById(R.id.message);//內容 Button leftBtn = (Button)myView.findViewById(R.id.cancel);//左側按鈕 View leftDeliver = (View)myView.findViewById(R.id.leftdeliver);//左側按鈕右側的中豎線 Button betweenBtn = (Button)myView.findViewById(R.id.between);//中間按鈕 Button rightBtn = (Button)myView.findViewById(R.id.confirm);//右側按鈕 View rightDeliver = (View)myView.findViewById(R.id.rightdeliver);//右側按鈕左側的中豎線 //==========================初始展現========================== if(mDialogSetListener != null){ mDialogSetListener.setDialog(title, message, leftBtn, betweenBtn, rightBtn); } //如果標題文字不存在,則隱藏標題中橫線 if(title.getVisibility() == View.GONE){ titleDelever.setVisibility(View.GONE); } //如果內容文字不存在,則隱藏標題中橫線 if(message.getVisibility() == View.GONE){ titleDelever.setVisibility(View.GONE); } //如果左側按鈕不存在,則隱藏左側按鈕旁邊的中豎線,中間按鈕的背景修改為原左側按鈕的背景 if(leftBtn.getVisibility() == View.GONE) { leftDeliver.setVisibility(View.GONE); betweenBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_left_btn_bg)); if(betweenBtn.getVisibility() == View.GONE) { rightDeliver.setVisibility(View.GONE); rightBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); }else if(rightBtn.getVisibility() == View.GONE) { rightDeliver.setVisibility(View.GONE); betweenBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); } } //如果中間按鈕不存在,則隱藏左側按鈕旁邊的中豎線 if(betweenBtn.getVisibility() == View.GONE) { leftDeliver.setVisibility(View.GONE); if(leftBtn.getVisibility() == View.GONE) { rightDeliver.setVisibility(View.GONE); rightBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); }else if(rightBtn.getVisibility() == View.GONE){ rightDeliver.setVisibility(View.GONE); leftBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); } } //如果右側按鈕不存在,則隱藏右側按鈕旁邊的中豎線,中間按鈕的背景修改為原右側按鈕的背景 if(rightBtn.getVisibility() == View.GONE) { rightDeliver.setVisibility(View.GONE); betweenBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_right_btn_bg)); if(betweenBtn.getVisibility() == View.GONE) { leftDeliver.setVisibility(View.GONE); leftBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); }else if(leftBtn.getVisibility() == View.GONE) { leftDeliver.setVisibility(View.GONE); betweenBtn.setBackgroundDrawable(ContextCompat.getDrawable(getActivity(),R.drawable.dialog_confirm_cancel_btnlayout_bg)); } } mTag = this.getTag(); Log.e(TAG, "mTag="+mTag); //==========================初始化監聽事件========================== leftBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(mDialogClickListener != null){ mDialogClickListener.cancelClickListener(); } dismiss(); } }); betweenBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(mDialogClickListener != null){ mDialogClickListener.betweenClickListener(); } dismiss(); } }); rightBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(mDialogClickListener != null){ mDialogClickListener.confirmClickListener(); } dismiss(); } }); } /**設置對話框內容和樣式的監聽器(標題、內容、按鈕樣式,包括控制隱藏)*/ public static abstract interface DialogSetListener { /**設置標題、內容、按鈕的文本以及按鈕的顯示隱藏 * @param title - 標題控件【默認“提示”】 * @param message - 內容控件【默認空白】 * @param leftBtn - 左側按鈕控件【默認“取消”】 * @param betweenBtn - 中間按鈕控件【默認空白】 * @param rightBtn - 右側按鈕控件【默認“確定”】*/ public abstract void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn); } /**三個按鈕的點擊事件監聽器*/ public static abstract interface DialogClickListener { /**中間按鈕*/ public abstract void betweenClickListener(); /**取消按鈕*/ public abstract void cancelClickListener(); /**確定按鈕*/ public abstract void confirmClickListener(); //返回鍵觸發的事件接口 public abstract void onDismissListener(); } public void setDialogClickListener(DialogClickListener dialogClickListener) { mDialogClickListener = dialogClickListener; } }
將布局文件dialog_confirm_cancel.xml復制到項目的res/layout目錄中

<?xml version="1.0" encoding="utf-8"?> <!-- 確認對話框樣式【含有標題、左中右三個按鈕】布局文件 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/transparent" android:gravity="center" > <RelativeLayout android:id="@+id/relativeLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/confirm_cancel_dialog_margin" android:layout_marginRight="@dimen/confirm_cancel_dialog_margin" android:background="@drawable/dialog_confirm_cancel_bg" > <!-- 標題 --> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/confirm_cancel_title" android:textColor="@color/confirm_cancel_dialog_title_color" android:textSize="@dimen/confirm_cancel_dialog_title_text_size" android:padding="@dimen/confirm_cancel_dialog_title_padding"/> <!-- 標題下的中橫線 --> <TextView android:id="@+id/delever_up_message" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@id/title" android:layout_marginLeft="@dimen/confirm_cancel_dialog_delever_margin" android:layout_marginRight="@dimen/confirm_cancel_dialog_delever_margin" android:background="@color/confirm_cancel_dialog_delever_h_color" /> <!-- 內容 --> <TextView android:id="@+id/message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/delever_up_message" android:gravity="center" android:textColor="@color/confirm_cancel_dialog_message_color" android:text="" android:textSize="@dimen/confirm_cancel_dialog_message_text_size" android:paddingTop="@dimen/confirm_cancel_dialog_message_padding" android:paddingBottom="@dimen/confirm_cancel_dialog_message_padding" android:paddingLeft="@dimen/confirm_cancel_dialog_title_padding" android:paddingRight="@dimen/confirm_cancel_dialog_title_padding"/> <!-- 內容下的中橫線 --> <View android:id="@+id/delever_down_message" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@id/message" android:layout_marginLeft="@dimen/confirm_cancel_dialog_delever_margin" android:layout_marginRight="@dimen/confirm_cancel_dialog_delever_margin" android:background="@color/confirm_cancel_dialog_delever_v_color" /> <!-- 底部按鈕區域 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/delever_down_message" android:orientation="horizontal" android:background="@android:color/transparent" > <!-- 取消按鈕 --> <Button android:id="@+id/cancel" android:layout_width="0.0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/dialog_confirm_cancel_left_btn_bg" android:gravity="center" android:text="@string/confirm_cancel_left_btn" android:textStyle="bold" android:textColor="@color/confirm_cancel_dialog_btn_ctext_color" android:textSize="@dimen/confirm_cancel_dialog_btn_text_size" android:paddingTop="@dimen/confirm_cancel_dialog_title_padding" android:paddingBottom="@dimen/confirm_cancel_dialog_title_padding" /> <!-- 取消按鈕旁邊的中豎線 --> <View android:id="@+id/leftdeliver" android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/confirm_cancel_dialog_delever_v_color" android:orientation="vertical" /> <!-- 中間按鈕 --> <Button android:id="@+id/between" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:background="@drawable/dialog_confirm_cancel_center_btn_bg" android:gravity="center" android:text="" android:textStyle="bold" android:textColor="@color/confirm_cancel_dialog_btn_ctext_color" android:textSize="@dimen/confirm_cancel_dialog_btn_text_size" android:paddingTop="@dimen/confirm_cancel_dialog_title_padding" android:paddingBottom="@dimen/confirm_cancel_dialog_title_padding" /> <!-- 確定按鈕旁邊的中豎線 --> <View android:id="@+id/rightdeliver" android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/confirm_cancel_dialog_delever_v_color" android:orientation="vertical" /> <!-- 確定按鈕 --> <Button android:id="@+id/confirm" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:background="@drawable/dialog_confirm_cancel_right_btn_bg" android:gravity="center" android:text="@string/confirm_cancel_right_btn" android:textStyle="bold" android:textColor="@color/confirm_cancel_dialog_btn_ctext_color" android:textSize="@dimen/confirm_cancel_dialog_btn_text_size" android:paddingTop="@dimen/confirm_cancel_dialog_title_padding" android:paddingBottom="@dimen/confirm_cancel_dialog_title_padding" /> </LinearLayout> </RelativeLayout> </RelativeLayout>
將drawable目錄中的文件復制到項目中
在colors.xml文件中添加以下代碼
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <!-- ==================確認取消對話框================== --> <!-- 對話框的邊框顏色 --> <color name="confirm_cancel_dialog_stroke_color">#00ffffff</color> <!-- 對話框的填充顏色 --> <color name="confirm_cancel_dialog_solid_color">#ffffffff</color> <!-- 對話框的標題顏色 --> <color name="confirm_cancel_dialog_title_color">#0164C5</color> <!-- 對話框的中橫線顏色 --> <color name="confirm_cancel_dialog_delever_h_color">#0164C5</color> <!-- 對話框的中豎線顏色 --> <color name="confirm_cancel_dialog_delever_v_color">#80DFDFDF</color> <!-- 對話框的內容顏色 --> <color name="confirm_cancel_dialog_message_color">#6A6A6A</color> <!-- 對話框的按鈕背景默認顏色 --> <color name="confirm_cancel_dialog_btn_def_color">#00ffffff</color> <!-- 對話框的按鈕背景觸發顏色 --> <color name="confirm_cancel_dialog_btn_click_color">#00ffffff</color> <!-- 對話框的按鈕文字顏色 --> <color name="confirm_cancel_dialog_btn_ctext_color">#000000</color> </resources>
在dimens.xml文件中添加以下代碼
<resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <!-- ==================確認取消對話框================== --> <!-- 對話框的圓角角度 --> <dimen name="confirm_cancel_dialog_corners">5dp</dimen> <!-- 對話框的整體外邊距 --> <dimen name="confirm_cancel_dialog_margin">40dp</dimen> <!-- 對話框的標題內邊距 --> <dimen name="confirm_cancel_dialog_title_padding">10dp</dimen> <!-- 對話框的標題大小 --> <dimen name="confirm_cancel_dialog_title_text_size">18sp</dimen> <!-- 中橫線的外邊距 --> <dimen name="confirm_cancel_dialog_delever_margin">1dp</dimen> <!-- 對話框的內容內邊距 --> <dimen name="confirm_cancel_dialog_message_padding">25dp</dimen> <!-- 對話框的內容大小 --> <dimen name="confirm_cancel_dialog_message_text_size">16sp</dimen> <!-- 對話框的按鈕大小 --> <dimen name="confirm_cancel_dialog_btn_text_size">16sp</dimen> </resources>
在strings.xml文件中添加以下代碼
<resources> <string name="app_name">ConfirmCancelDialogDemo</string> <!-- ************確認取消對話框************ --> <string name="confirm_cancel_title">提示</string> <string name="confirm_cancel_right_btn">確定</string> <string name="confirm_cancel_left_btn">取消</string> <string name="confirm_between_btn">保存</string> </resources>
三、使用方法
只展現一個確定按鈕
btn_confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ConfirmCancelDialog dialog = ConfirmCancelDialog.getInstance(MainActivity.this,true,new ConfirmCancelDialog.DialogSetListener() { public void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn) { message.setText("請檢查用戶名"); leftBtn.setVisibility(GONE); betweenBtn.setVisibility(GONE); } }); dialog.setDialogClickListener(new ConfirmCancelDialog.DialogClickListener() { @Override public void betweenClickListener() { // TODO Auto-generated method stub } @Override public void cancelClickListener() { // TODO Auto-generated method stub } @Override public void confirmClickListener() { Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show(); } @Override public void onDismissListener() { } }); dialog.show(getSupportFragmentManager(), "confirmDialog"); } });
展現確定和取消兩個按鈕
btn_confirmcancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ConfirmCancelDialog dialog = ConfirmCancelDialog.getInstance(MainActivity.this,new ConfirmCancelDialog.DialogSetListener() { public void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn) { message.setText("是否退出?"); betweenBtn.setVisibility(GONE); } }); dialog.setDialogClickListener(new ConfirmCancelDialog.DialogClickListener() { @Override public void betweenClickListener() { // TODO Auto-generated method stub } @Override public void cancelClickListener() { Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT).show(); } @Override public void confirmClickListener() { Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show(); } @Override public void onDismissListener() { } }); dialog.show(getSupportFragmentManager(), "confirmCancelDialog"); } });
展現三個按鈕,並且修改了按鈕的文本
btn_confirmcancelbetween.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ConfirmCancelDialog dialog = ConfirmCancelDialog.getInstance(MainActivity.this,new ConfirmCancelDialog.DialogSetListener() { public void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn) { message.setText("是否保存?"); betweenBtn.setText("不保存"); rightBtn.setText("保存"); } }); dialog.setDialogClickListener(new ConfirmCancelDialog.DialogClickListener() { @Override public void betweenClickListener() { Toast.makeText(MainActivity.this,"不保存",Toast.LENGTH_SHORT).show(); } @Override public void cancelClickListener() { Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT).show(); } @Override public void confirmClickListener() { Toast.makeText(MainActivity.this,"保存",Toast.LENGTH_SHORT).show(); } @Override public void onDismissListener() { } }); dialog.show(getSupportFragmentManager(), "confirmCancelBetweenDialog"); } });
展現沒有標題的對話框
btn_notitle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ConfirmCancelDialog dialog = ConfirmCancelDialog.getInstance(MainActivity.this,new ConfirmCancelDialog.DialogSetListener() { public void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn) { message.setText("發現新版本,是否升級?"); title.setVisibility(GONE); betweenBtn.setVisibility(GONE); } }); dialog.setDialogClickListener(new ConfirmCancelDialog.DialogClickListener() { @Override public void betweenClickListener() { // TODO Auto-generated method stub } @Override public void cancelClickListener() { Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT).show(); } @Override public void confirmClickListener() { Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show(); } @Override public void onDismissListener() { } }); dialog.show(getSupportFragmentManager(), "noTitleDialog"); } });
展現內容文本很多的對話框(需要手動設置居左對齊)
btn_message.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ConfirmCancelDialog dialog = ConfirmCancelDialog.getInstance(MainActivity.this,new ConfirmCancelDialog.DialogSetListener() { public void setDialog(TextView title, TextView message, Button leftBtn, Button betweenBtn, Button rightBtn) { message.setText("當內容文本很多的時候,可以手動設置居左【message.setGravity(Gravity.LEFT)】"); message.setGravity(Gravity.LEFT);//如果內容很多的話,需要手動設置居左 betweenBtn.setVisibility(GONE); } }); dialog.setDialogClickListener(new ConfirmCancelDialog.DialogClickListener() { @Override public void betweenClickListener() { // TODO Auto-generated method stub } @Override public void cancelClickListener() { Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT).show(); } @Override public void confirmClickListener() { Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show(); } @Override public void onDismissListener() { } }); dialog.show(getSupportFragmentManager(), "noMessageDialog"); } });
混淆配置
無
參考資料
暫時空缺