在開發的過程中,dialog的使用場景非常的多,而在系統原生的dialog不能滿足我們要求的時候,通常會需要自己來自定義一個dialog,下面就簡單的介紹一下自定義dialog.
在此,先給一個具體的應用場景吧,我們的dialog是一個密碼輸入框,需要彈出一個對話框,要求輸出密碼,并對密碼進行校驗,正確的話,則dialog消失,錯誤的話,則有一個錯誤提示,好了,需求就介紹到這里,下面就開始寫我們的代碼吧!
在這里我們暫且寫一個CustomDialog,在它的onCreate()初始化的方法里面,設置我們的布局文件,另外在它的構造方法里面設置我們的dialog樣式
public class CustomDialog extends Dialog { public CustomDialog(Context context) { //dialog的樣式 super(context, R.style.MyDialog); } @Override PRotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_dialog); //設置點擊dialog窗體外部是否可以關閉dialog,false代表不能關閉 setCanceledOnTouchOutside(false); }}上面的 R.style.MyDialog 是我們自己定義的dialog的樣式,存放在values/style目錄之下,MyDialog脫胎于系統原生的Theme.Dialog,我們只是對它的樣式稍微做了修改.
<!--自定義dialog背景全透明無邊框theme --><style name="MyDialog" parent="android:style/Theme.Dialog"> <!--背景顏色及和透明程度--> <item name="android:windowBackground">@android:color/transparent</item> <!--是否去除標題 --> <item name="android:windowNoTitle">true</item> <!--是否去除邊框--> <item name="android:windowFrame">@null</item> <!--是否浮現在activity之上--> <item name="android:windowIsFloating">true</item> <!--是否模糊--> <item name="android:backgroundDimEnabled">true</item></style>下面貼一下xml布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="300dp" android:layout_height="match_parent" android:background="@drawable/shape_dialog_bg" android:orientation="vertical"> <RelativeLayout android:layout_marginTop="20dp" android:layout_gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_psw_remove" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_centerVertical="true" android:layout_margin="10dp" android:text="取消" android:textColor="#234" android:textSize="16dp"/> <TextView android:id="@+id/dialog_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_margin="10dp" android:text="請輸入密碼" android:textColor="#404040" android:textSize="20dp"/> </RelativeLayout> <EditText android:background="@drawable/shape_dialog_edt_input" android:id="@+id/et_psw_input" android:padding="8dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:layout_marginTop="8dp" android:gravity="center" android:textSize="16dp" android:inputType="numberPassWord" android:hint="請輸入密碼" android:textColor="#000"/> <TextView android:id="@+id/tv_psw_error" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="12dp" android:text="密碼錯誤" android:textColor="#d94641" android:textSize="16dp" android:visibility="invisible"/> <LinearLayout android:layout_marginTop="20dp" android:layout_marginBottom="12dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:background="@drawable/shape_dialog_btn_confirm" android:padding="10dp" android:layout_marginLeft="20dp" android:layout_marginRight="10dp" android:id="@+id/tv_psw_cancel" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="取消" android:gravity="center_horizontal" android:textColor="#fff" android:textSize="16dp"/> <TextView android:padding="10dp" android:background="@drawable/shape_dialog_btn_confirm" android:layout_marginLeft="10dp" android:layout_marginRight="14dp" android:id="@+id/tv_psw_confirm" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:gravity="center_horizontal" android:text="確認" android:textColor="#fff" android:textSize="16dp"/> </LinearLayout></LinearLayout>在這里就以 確定 監聽為例,其他的就不在此贅述.
//設置確定按鈕的點擊事件 mTvConfirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //當確定鍵被點擊了之后,我們需要通知外界,用戶點擊了確認,那么這個時候,我們需要使用接口回調 } });當確定鍵被點擊了之后,我們需要通知外界,用戶點擊了確認,那么這個時候,我們需要使用接口回調
/** * 設置確定按鈕和取消被點擊的接口 */ public interface onConfirmOnclickListener { void onConfirmlick(String psw, TextView error); } /** * 設置確定按鈕的顯示內容和監聽 * * @param str 這里的string其實就是 "確認" 這倆字,但是有時候我們需要的不是確認倆字而是 "是"這一個字的時候,直接傳進來就ok了 * @param onConfirmOnclickListener */ public void setConfirmOnclickListener(String str, onConfirmOnclickListener onConfirmOnclickListener) { if (str != null) { confirmStr = str; } this.confirmOnclickListener = onConfirmOnclickListener; }接口回調方法寫好之后,那么我們就可以這樣的對確定鍵進行監聽了
//設置確定按鈕被點擊后,向外界提供監聽 mTvConfirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (confirmOnclickListener != null) { //第一個參數是拿到密碼輸入框的輸入密碼 //第二個參數是錯誤信息的 textview,如果密碼正確就gone confirmOnclickListener.onConfirmlick(mEtInput.getText().toString().trim(), mTvError); } } });好了,下面開始在項目中使用一下.
/** * 彈出密碼輸入框 */ final CustomDialog customDialog = new CustomDialog(context); customDialog.setConfirmOnclickListener("確定", new CustomDialog.onConfirmOnclickListener({ @Override public void onConfirmlick(String psw, final TextView error) { if ("".equals(psw)) { Toast.makeText(context,"密碼不能為空!",Toast.LENGTH_SHORT).show(); } else if (!"123456".equals(psw)) { //這里的默認正確密碼就設置為 123456 error.setVisibility(View.VISIBLE); } else { customDialog.dismiss(); } } }); customDialog.show();
到了這里,確定鍵的監聽及使用算是完了,剩下的取消監聽,邏輯都是一樣的,就不貼出來了.但是不知道你們有沒有發覺,這樣看起來仍然是非常的臃腫,如果在項目里面有好幾個地方都要使用,那么我們要寫很多次這樣的方法,于是我們可以對這個dialog進行再次的封裝
我在這里寫了一個DialogUtils的工具類,里面是這樣的,里面有一個showpswDialog的靜態方法,并且又分別在”確定”和”取消”里面再次寫了兩個接口回調,對dialog進行二次監聽,這樣做的好處就是,當我們點擊 “確定”或”取消”不需要有什么動作,那么我們就不用再實現這些臃腫的接口;需要有動作的時候,就實現DialogUtils里面的接口
/** * 彈出密碼輸入框 */public static void showPswDialog(final Activity context) { final CustomDialog customDialog = new CustomDialog(context); customDialog.setConfirmOnclickListener("確定", new CustomDialog.onConfirmOnclickListener() { @Override public void onConfirmlick(String psw, final TextView error) { if ("".equals(psw)) { Toast.makeText(context,"密碼不能為空!",Toast.LENGTH_SHORT).show(); } else if (!"123456".equals(psw)) { error.setVisibility(View.VISIBLE); //兩秒鐘之后,取消錯誤信息提醒 new Handler().postDelayed(new Runnable() { @Override public void run() { error.setVisibility(View.INVISIBLE); } }, 2000); } else { if (mOnDialogConfirmListener != null) { mOnDialogConfirmListener.onDialogConfirm(""); } customDialog.dismiss(); } } }); //取消dialog customDialog.setCancelOnclickListener("取消", new CustomDialog.onCancelOnclickListener() { @Override public void onCancelClick() { if (mOnDialogCancelListener != null) { mOnDialogCancelListener.onDialogCancel(); } customDialog.dismiss(); } }); customDialog.show();}同樣的,只貼出確定的接口回調
/** * dialog確定鍵的接口 */public interface OnDialogConfirmListener { void onDialogConfirm(String num);}/** * dialog確定鍵的接口回調方法 * @param onDialogConfirmListener */public static void setOnDialogConfirmListener(OnDialogConfirmListener onDialogConfirmListener) { mOnDialogConfirmListener = onDialogConfirmListener;}二次封裝之后,我們再來看看使用的代碼
DialogUtils.showPswDialog(MainActivity.this);只此一行,就可以彈出dialog,還可以確認,取消,驗證密碼 是不是很方便?
當點擊確定鍵需要有動作的時候,我們就這樣
DialogUtils.setOnDialogConfirmListener(new DialogUtils.OnDialogConfirmListener() { @Override public void onDialogConfirm(String num) { Toast.makeText(context,"密碼是:" + num,Toast.LENGTH_SHORT).show(); } });DialogUtils.setOnDialogCancelListener(new DialogUtils.OnDialogCancelListener() { @Override public void onDialogCancel() { Toast.makeText(MainActivity.this,"取消了...",Toast.LENGTH_SHORT).show(); } });
下面是源碼下載的路徑:http://download.csdn.net/detail/itchaosfun/9748928 這是小弟第一次發博,還請多多指教!
新聞熱點
疑難解答