简单实现自定义Dialog弹窗

2023-04-11 13:18:19

前言

这几天都在学习Web端的技术点,对于Android这么好玩的技术,那么也不能丢落。时间挤一挤,说不定还能挤出一条沟,呵呵..这几天看到小伙伴们在项目中在为dialog相关的问题不知所措,看了大概的需求,都涉及到自定义dialog,其实也蛮简单的,在日常开发中遇到自定义dialog的需求还是蛮多的,所以挤点时间出来练练手先.

Ⅰ.简述

看看小伙伴的效果图

效果图1

这里写图片描述

效果图2

这里写图片描述

看上面的效果图,应该不是很难吧,Android系统提供的dialog往往都不满足产品的需求,所以就需要自定义了,那么先简单说说怎么实现的吧!主要就是继承dialog类,然后给其设置布局,再进行点击事件的回调等等

Ⅱ.自定义Dialog实现

以上面图1为效果图,首页先来个布局,那么下面简单看下布局吧


    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:id="@+id/container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true">

            <TextView
                android:id="@+id/bg"
                android:layout_width="250dp"
                android:layout_height="160dp"
                android:background="#c9f4fe"
                android:layout_below="@+id/iv_success"
                android:text="成功领取优惠劵"
                android:gravity="bottom|center"
                android:textColor="#0096ff"
                android:textSize="16sp"/>

            <ImageView
                android:id="@+id/iv_success"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/receive_success"
                android:layout_centerInParent="true"/>

        </RelativeLayout>


        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="@drawable/receive_success_close"
            android:layout_alignRight="@id/container"
            android:layout_marginTop="150dp" />


        <Button
            android:id="@+id/share"
            android:layout_width="250dp"
            android:layout_height="60dp"
            android:background="#0096ff"
            android:layout_below="@id/container"
            android:layout_centerHorizontal="true"
            android:text="立即分享"
            android:textSize="18sp"
            android:textColor="#ffffff"/>

    </RelativeLayout>

本来接着是要继承dialog并给其设置上面的布局,但是考虑到项目中对dialog弹窗的使用频率还是挺高的,所以简单抽取dialog,以抽象类的方式提供给其他dialog去继承,那么下面看看抽取的BaseDialog的代码:


    /**
     * Created by wyk on 2016/12/28.
     */
    public abstract class BaseDialog extends Dialog implements View.OnClickListener{

        public Context mContext;

        public BaseDialog(Context context){
            super(context);
            this.mContext = context;
            initView();
        }

        public BaseDialog(Context context, int themeResId){
            super(context,themeResId);
            this.mContext = context;
            initView();
        }

        public abstract void initView();
        public abstract void onDialogClick(View v);

        /** 查找子控件,省强转 */
        public <T> T findView(int id) {
            T view = (T) findViewById(id);
            return view;
        }

        public void showToast(String text) {    //Toast
            //tell user
        }

        @Override
        public void onClick(View v) {           //点击事件
            onDialogClick(v);
        }
    }

接着就来实现自定义的dialog,自定义的dialog继承自BaseDialog,看下面代码:


    /**
     * Created by wyk on 2016/12/28.
     */
    public class MyDialog extends BaseDialog{
        //dialog对应布局上的点击事件,该接口进行回调
        private OnCallResult mOnCallResult;
        private Button mBtnCancel;
        private Button mBtnShare;

        public MyDialog(Context context) {
            super(context);
            initDate();
            initListener();
        }

        /** 设置事件的回调接口*/
        public void setCallBackListen(OnCallResult onCallResult){
            mOnCallResult = onCallResult;
        }

        /**该方法提供于操作布局控件*/
        @Override
        public void initView() {
            Window window = getWindow();
            window.requestFeature(Window.FEATURE_NO_TITLE);
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            setContentView(R.layout.page_dialog);

            WindowManager.LayoutParams params = window.getAttributes();
            params.gravity = Gravity.CENTER;
            //这里是设置dialog弹出、隐藏的动画效果
            //params.windowAnimations = R.style.MyDialogAnimation;      


            mBtnCancel = findView(R.id.btn_cancel);
            mBtnShare = findView(R.id.share);
        }
        /**该方法提供于操作数据*/
        public void initDate() {
        }
        /**该方法提供于设置监听事件*/
        public void initListener() {
            mBtnCancel.setOnClickListener(this);
            mBtnShare.setOnClickListener(this);
        }
        /**布局的监听函数*/
        @Override
        public void onDialogClick(View v) { 
            if(mOnCallResult!=null){
                switch (v.getId()) {
                    case R.id.btn_cancel:               //取消监听
                       // MyDialog.this.cancel();
                        mOnCallResult.onCancel();
                        break;
                    case R.id.share:                    //分享监听
                        mOnCallResult.onShare();
                        break;
                    default:
                        break;
                }
            }
        }
    }

上面代码的OnCallResult对象,注释是回调的接口,可是OnCallResult长怎样的呢??看下面代码

    /**
     * Created by WYK on 2016/12/28.
     */
    public interface OnCallResult {

        void onCancel();
        void onShare();
    }

Ⅲ.效果展示

上面的代码逻辑应该还是比较清晰的,都做了注释说明,力求做到简单易懂,接着使用上面自定义的MyDialog,看看效果如何。为了实现方便,就在MainActivity的布局上添加一个按钮,点击该按钮弹出MyDialog,然后可点击取消dialog等,看代码:

    /**
     * Created by wyk on 2016/12/28.
     */
    public class MainActivity extends AppCompatActivity {
        private Button mShowDialog;
        private MyDialog mDialog;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initListener();
        }

        /**该方法提供于操作布局控件*/
        private void initView() {
            mShowDialog = (Button) findViewById(R.id.btn_show_dialog);
            mDialog = new MyDialog(this);
        }

        /**该方法提供于设置监听事件*/
        private void initListener() {
            mDialog.setCallBackListen(new OnCallResult() {
                @Override
                public void onCancel() {
                    mDialog.cancel();
                }
                @Override
                public void onShare() {
                    Toast.makeText(MainActivity.this, "Share Success!!!", Toast.LENGTH_SHORT).show();
                    mDialog.show();
                }
            });
            mShowDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mDialog.show();
                }
            });
        }

        @Override
        protected void onDestroy() {        
            super.onDestroy();
            if(mDialog!=null){              //防止突发状态造成 窗体泄露
                mDialog.cancel();           
                mDialog = null;
            }
        }
    }

下面是MainActivity的布局,顺便也贴上

    <!--activity_main布局-->
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.wyk.dialogtest.MainActivity">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="show dialog"
            android:id="@+id/btn_show_dialog"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="173dp" />
    </RelativeLayout>

上面的操作基本可以展示MyDialog,也可以点击取消/点击进行分享(分享代码略),布局和代码都很简单吧,也没什么逻辑,就这样完成了,是不是挺So easy 的。在项目开发中,dialog的坑还是蛮多的,比如上面MainActivity标识出来的窗体泄露,找时间再写篇文章总结下遇到的坑。还有1点没说的,应该看到上面的BaseDialog里的 “params.windowAnimations = R.style.MyDialogAnimation; “这一行注释的代码吧,这个是设置Dialog弹出、隐藏的动画效果,之前有篇文章已经提到,下面是Dialog动画效果那篇文章的地址,这里就不扯了。

Dialog动画效果文章Url:http://blog.csdn.net/yk377657321/article/details/51708385

最后还是来看看上面代码运行的效果图(布局丑死咯~~~怪我了):
这里写图片描述

Ⅳ.总结

  • 1.在浏览了Dialog的代码,其实针对BaseDialog还可以进一步抽取的,笔者追求实用即可,就不再抽取了

  • 2.针对项目中Dialog的坑,打算之后再写个文章记录下,这就当留个空白吧!

  • 3.2016还剩几天,抓紧时间,别让心长野草了。

    扯了这么多,呜呜···还是先撤了。

  • 作者:巨头之路
  • 原文链接:https://blog.csdn.net/yk377657321/article/details/53907376
    更新时间:2023-04-11 13:18:19