开发中,相信经常会用到弹窗的这种交互设计,我比较喜欢用PopupWindow自定义布局,之前也写了关于它的总结,所以很少会考虑到dialog,虽然有些弹框用dialog会更方便些,然后最近在写弹窗的时候,遇到一个比较郁闷的问题,EditText嵌入到PopupWindow,在EditText获得焦点的情况下软键盘不会自动弹起,最开始我还以为是我的某些属性没设置才导致的, 后来百度才发现自己想的简单了。后来还是决定用dialog。原因有这些:1.软键盘不会自动弹起 2.用代码让软键盘弹出,但是还得用代码让其收回 3.popupWindow下的界面控件仍然能响应事件 4.弹起的软键盘会被popupwindow遮盖等,处理起来感觉很麻烦。
用了dialog后发现原来是我想的麻烦了,之前也不是没用过dialog,只是不喜欢sdk中ThemeStyle,所以一直来就偏向PopupWindow些。其实这也是只是一个简单的自定义dialog。获取验证码,然后用CountDownTimer实现倒计时。Dialog可以自己适配键盘的弹起和收缩。
自定义Dialog类然后集成Dialog,和自定义控件差不多,实现3个构造参数,在两个参数的构造方法中设置style,Dialog具有生命周期方法,所以写起来并不费劲。下面直接贴代码好了。
public class MessageCodeCheckDialog extends Dialog implements View.OnClickListener {
private TextView tv_code_title;
private TextView tv_des_code;
private EditText et_msg_code;
private TextView tv_tiem_count;
private CountDownTimer codeTimer;
private TextView tv_cancle;
private TextView tv_ensure;
private DialogCallBack callBack;
public MessageCodeCheckDialog(@NonNull Context context) {
super(context);
}
public MessageCodeCheckDialog(@NonNull Context context, int themeResId) {
super(context, R.style.Translucent_NoTitle);
}
protected MessageCodeCheckDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.popup_message_code);
initView();
}
/**
*取消倒计时
*/
public void timerCancle() {
if (codeTimer != null) {
codeTimer.cancel();
}
tv_tiem_count.setText("重新获取");
tv_tiem_count.setClickable(true);
}
public void startTimer(){
codeTimer.start();
//开启倒计时后,不可点击
tv_tiem_count.setClickable(false);
}
public void setNumberAndName(String phoneNumer,String valueName){
tv_code_title.setText("是否确认修改"+valueName);
tv_des_code.setText("验证码已发送至");
}
private void initView() {
tv_code_title = (TextView) findViewById(R.id.tv_title);
tv_des_code = (TextView) findViewById(R.id.tv_des);
et_msg_code = (EditText) findViewById(R.id.et_msg_code);
tv_tiem_count = (TextView) findViewById(R.id.tv_time_count);
tv_cancle = (TextView) findViewById(R.id.tv_cancel);
tv_ensure = (TextView) findViewById(R.id.tv_ensure);
tv_code_title.setText("是否确认修改");
tv_des_code.setText("验证码已发送至");
tv_tiem_count.setText("获取验证码");
//倒计时结束
codeTimer = new CountDownTimer(90 * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
tv_tiem_count.setText("还剩" + millisUntilFinished / 1000 + "秒");
}
@Override
public void onFinish() {
//倒计时结束
tv_tiem_count.setText("重新获取");
tv_tiem_count.setClickable(true);
}
};
tv_tiem_count.setOnClickListener(this);
tv_cancle.setOnClickListener(this);
tv_ensure.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_time_count:
//获取验证码
if (callBack != null) {
callBack.getCode();
}
break;
case R.id.tv_cancel:
if (callBack != null) {
callBack.cancle();
}
break;
case R.id.tv_ensure:
String msg_code = et_msg_code.getText().toString().trim();
if (TextUtils.isEmpty(msg_code)) {
ToastUtil.showToast("请填写验证码");
} else {
if (callBack != null) {
callBack.ensure(msg_code);
}
dismiss();
}
break;
}
}
public void setDialogCallBack(DialogCallBack callBack) {
this.callBack = callBack;
}
public interface DialogCallBack {
public void getCode();
public void cancle();
public void ensure(String code);
}
}
在activity中使用也很方便,new一个实例后就可以直接show
messageCodeCheckDialog = new MessageCodeCheckDialog(this);
messageCodeCheckDialog.setDialogCallBack(new MessageCodeCheckDialog.DialogCallBack() {
@Override
public void getCode() {
//获取验证码
if (Util.isMobileNO(UserManager.getPhoneNum())) {
ApiVerificationCode(UserManager.getPhoneNum());
messageCodeCheckDialog.startTimer();
} else {
ToastUtil.showToast("用户手机号不正确");
}
}
@Override
public void cancle() {
messageCodeCheckDialog.dismiss();
}
@Override
public void ensure(String msg_code) {
//TODO 验证验证码
}
});
messageCodeCheckDialog.show();
我把定义的style也添出来好了,后面自己用也可以直接复制粘贴了
<style name="Translucent_NoTitle" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:background">#00000000</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowAnimationStyle">@style/dialogWindowAnim</item>
</style>
style中用到的动画
<style name="dialogWindowAnim" mce_bogus="1" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/dialog_down_in</item>
<item name="android:windowExitAnimation">@anim/dialog_down_out</item>
</style>
dialog_down_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<translate
android:duration="300"
android:fromYDelta="100%"
android:fromXDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
dialog_down_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<translate
android:duration="300"
android:fromYDelta="0%"
android:fromXDelta="0%"
android:toXDelta="0%"
android:toYDelta="100%" />
</set>
下面是一个dialog工具类,简单dailog比较加载进度,提示,多条目选择等,方便实用
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.TextUtils;
/**
* 对话框辅助类
*/
public class DialogUtil {
/***
* 获取一个dialog
* @param context
* @return
*/
public static AlertDialog.Builder getDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
return builder;
}
/***
* 获取一个耗时等待对话框
* @param context
* @param message
* @return
*/
public static ProgressDialog getWaitDialog(Context context, String message) {
ProgressDialog waitDialog = new ProgressDialog(context);
if (!TextUtils.isEmpty(message)) {
waitDialog.setMessage(message);
}
return waitDialog;
}
/***
* 获取一个信息对话框,注意需要自己手动调用show方法显示
* @param context
* @param message
* @param onClickListener
* @return
*/
public static AlertDialog.Builder getMessageDialog(Context context, String message, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(message);
builder.setPositiveButton("确定", onClickListener);
return builder;
}
public static AlertDialog.Builder getMessageDialog(Context context, String message) {
return getMessageDialog(context, message, null);
}
public static AlertDialog.Builder getConfirmDialog(Context context, String message, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(Html.fromHtml(message));
builder.setPositiveButton("确定", onClickListener);
builder.setNegativeButton("取消", null);
return builder;
}
public static AlertDialog.Builder getConfirmDialog(Context context, String message, DialogInterface.OnClickListener onOkClickListener, DialogInterface.OnClickListener onCancleClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(message);
builder.setPositiveButton("确定", onOkClickListener);
builder.setNegativeButton("取消", onCancleClickListener);
return builder;
}
public static AlertDialog.Builder getConfirmDialog(Context context,
String title,
String message,
String okString,
String cancelString,
DialogInterface.OnClickListener onOkClickListener,
DialogInterface.OnClickListener onCancelClickListener) {
AlertDialog.Builder builder = getDialog(context);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.setMessage(message);
builder.setPositiveButton(okString, onOkClickListener);
builder.setNegativeButton(cancelString, onCancelClickListener);
return builder;
}
public static AlertDialog.Builder getSelectDialog(Context context, String title, String[] arrays, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setItems(arrays, onClickListener);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.setPositiveButton("取消", null);
return builder;
}
public static AlertDialog.Builder getSingleChoiceDialog(Context context, String title, String[] arrays, int selectIndex, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setSingleChoiceItems(arrays, selectIndex, onClickListener);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.setNegativeButton("取消", null);
return builder;
}
}