Dialog 自定义

本文介绍了在开发中遇到PopupWindow中EditText焦点问题,导致软键盘无法自动弹起。作者转向使用Dialog,并详细阐述了自定义Dialog的过程,包括如何设置样式、实现倒计时功能,以及展示在Activity中的使用方式。通过自定义Dialog解决了PopupWindow下软键盘显示和事件响应的复杂性,提供了一个实用的Dialog工具类。
摘要由CSDN通过智能技术生成

    开发中,相信经常会用到弹窗的这种交互设计,我比较喜欢用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>
layout自己画就好了。Demo下载地址: https://download.csdn.net/download/reglog/10344497

下面是一个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;
    }


}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值