在开发的过程中,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 这是小弟第一次发博,还请多多指教!
新闻热点
疑难解答