美文网首页高级UI
Fragment(15)——通用dialog扩展使用

Fragment(15)——通用dialog扩展使用

作者: 奔跑的佩恩 | 来源:发表于2019-10-20 14:29 被阅读0次

    前言

    讲这篇文章时基于之前对DialogFragment知识的总结扩展。这节我们来讲DialogFragment实现自定义dialog。我将dialog的使用及相关设置都封装到了AppDialogFragment中,这节主要讲它的使用。

    今天涉及的内容:

    1. 创建一个dialog的准备
    2. 设置dialog显示大小
    3. dialog中控件初始化
    4. 一般dialog使用需要做的设置
    5. 给dialog设置圆角背景
    6. dialog设置背景遮罩
    7. dialog返回键的处理
    8. 其他方法
    9. 一个dialog调用的通常基本设置
    10. AppDialogFragment源码

    来波效果图
    全屏显示dialog


    1.gif

    按屏幕比例显示dialog


    2.gif
    设置dialog背景
    image.png
    设置背景遮罩
    4.gif

    拦截返回键


    5.gif

    一.创建一个dialog的准备

    AppDialogFragment作为一个dialog的父类,集中了dialog创建,展示需要的各种设置,它的出现是为了更加便捷的实现一个dialog。
    在你要写一个dialog(假设你的dialog命名为MyDialog),那么你可以继承AppDialogFragment,类似如下:

    public class MyDialog extends AppDialogFragment{
    
        @BindView(R.id.btn_test)
        Button mBtnTest;
    
        @Override
        protected double[] getWindowSize() {
            return new double[]{0.5,0.5};
        }
    
        @Override
        protected int getLayoutId() {
            return R.layout.dialog_fragment_test;
        }
    
        @Override
        protected void initData() {
    
        }
    
        @Override
        protected void setListener() {
    
        }
    }
    

    二. 设置dialog显示大小

    还是以创建的MyDialog为例,MyDialog的显示大小由以下方法确定

        @Override
        protected double[] getWindowSize() {
            return new double[]{width,height};
        }
    

    其中 width表示屏幕宽度比例,为float,height表示屏幕高度比例,为float。

    2.1 显示全屏dialog

    若要显示全屏,你可以在MyDialog中这样重写 getWindowSize() 方法

        @Override
        protected double[] getWindowSize() {
            return new double[]{super.MATCH_PARENT,super.MATCH_PARENT};
        }
    

    则dialog显示效果图如下


    1.gif
    2.2 显示比例大小dialog

    若要显示宽度是屏幕的0.8,高度是屏幕0.3大小的dialog,你可以像下面这样重写getWindowSize()

        @Override
        protected double[] getWindowSize() {
            return new double[]{0.8f,0.3f};
        }
    

    显示效果如下


    2.gif

    三.dialog中控件初始化

    假设你的MyDialog中有一个控件button,那么我们可以有两种方式来初始化它。

    3.1 利用getView()初始化控件

    //声明控件
    private Button mBtn;
    
    //初始化控件
    mBtn= (Button) getView(R.id.btn);
    

    3.2 利用butterknife初始化控件

    你先需要在你的项目中添加butterknife引用,在app对应的model中添加如下依赖:

    dependencies {
    
        //butterknife
        implementation 'com.jakewharton:butterknife:10.1.0'
        annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
    
        //其他引用省略
        //......
    
    }
    

    然后在你的MyDialog中这样初始化控件

        @BindView(R.id.btn)
        Button mBtn;
    

    四. 一般dialog使用需要做的设置

    新建一个NormalDialog,NormalDialog代码如下:

    package com.example.dialog;
    
    import android.widget.Button;
    
    import com.example.function.AppDialogFragment;
    import com.example.testdemo.R;
    
    /**
     * Title:
     * description:
     * autor:pei
     * created on 2019/9/4
     */
    public class NormalDialog extends AppDialogFragment {
    
    
        private Button mBtn;
    
        @Override
        protected double[] getWindowSize() {
            return new double[]{0.8f,0.3f};
        }
    
        @Override
        protected int getLayoutId() {
            return R.layout.normal_dialog;
        }
    
        @Override
        protected void initData() {
            mBtn= (Button) getView(R.id.btn);
        }
    
        @Override
        protected void setListener() {
    
        }
    }
    

    NormalDialog对应xml布局normal_dialog.xml代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:text="按钮"
            android:textAllCaps="false"
            android:textColor="#000000"
            android:textSize="16sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    以 NormalDialog为例,在MainActivity中调用的时候,你可以做些基本设置,示例调用如下:

            new NormalDialog()
                    .setCancel(true)//返回键是否关闭dialog,默认true
                    .setCancelOnTouchOutside(true)//屏幕外点击是否关闭,默认true
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    五.给dialog设置圆角背景

    先写一个圆角背景的xml文件,corner_bg.xml代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="#00ff00" />
        <corners android:radius="15dp"/>
    </shape>
    

    给dialog设置背景有两种方式

    • 在xml中设置背景
    • 用 setBackGroundId 方法在代码中设置背景

    这两种设置只能选择一种。

    5.1 在xml中设置背景

    以NormalDialog为例,你可以直接在其对应xml布局normal_dialog.xml中添加圆角背景,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:context=".MainActivity"
        android:background="@drawable/corner_bg">
    
       //其他代码省略
       //......
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    这时你需要在代码中配合使用 setRidShadow 方法,使用时范例如下:

           //圆角背景dialog
            new NormalDialog()
                    .setRidShadow(true)//设置为false会有圆角阴影,设置为true则不会有,默认为false
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    显示效果如下


    image.png

    若你此时设置 setRidShadow(false),则会出现如下现象


    image.png
    因此,当你是在xml中设置dalog背景的时候,则需要设置 setRidShadow(true)。
    注意 setRidShadow 方法只需要处理圆角背景的时候才调用
    5.2 用 setBackGroundId 方法在代码中设置背景

    当然,你也可以不在xml中设置圆角背景,而是直接在代码中设置圆角背景。在代码中设置背景如下(以设置圆角背景corner_bg为例):

            new NormalDialog()
                    .setBackGroundId(R.drawable.corner_bg)
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    显示效果如下


    image.png

    六. dialog设置背景遮罩

    给dialog设置背景遮罩主要涉及到两个方法

        /***
         * 设置dialog弹出时是否有遮罩覆盖界面
         * 默认为false,即无遮罩
         */
        setUIShadow(boolean uiShadow)
    
        /***
         * 设置dialog弹出时是否有遮罩覆盖界面
         * 默认为false,即无遮罩
         * uiShadowAlpha:遮罩弹出时的屏幕亮度(范围0f-1f,0f为黑色,1f为透明),默认为DEFAULT_UI_ALPHA,即0.6f
         */
         setUIShadow(boolean uiShadow,float uiShadowAlpha)
    

    当你不想给dialog弹出时设置遮罩的时候,你可以这样设置

            new NormalDialog()
                    .setUIShadow(false)//弹出时不显示遮罩
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    显示效果如下


    3.gif

    当然,你也可以不设置,因为dialog默认setUIShadow为false。
    如果,你想简单的设置一个背景遮罩,你可以这样

            new NormalDialog()
                    .setUIShadow(true)//弹出时显示遮罩
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    效果如下


    4.gif

    若你对背景遮罩的透明度有要求,那么你可以这样设置:

            new NormalDialog()
                    .setUIShadow(true,0.4f)//设置背景遮罩透明度0.4f
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    需要注意的是,当你想设置背景遮罩透明度的时候,setUIShadow(boolean uiShadow,float uiShadowAlpha) 方法中的 uiShadow需要设置为true,然后 uiShadowAlpha 范围为(范围0f-1f,0f为黑色,1f为透明)

    七. dialog返回键的处理

    设置点击返回键dialog消失的方法是:

    setCancel(true)//返回键是否关闭dialog,默认true
    

    若你要拦截dialog的返回键,则不能使用setCancel,而应该使用另一个方法:

    setOnDialogCancelListener(OnDialogCancelListener listener)
    

    下面给出dialog拦截返回键的示例:

            new NormalDialog()
                    .setOnDialogCancelListener(new AppDialogFragment.OnDialogCancelListener() {
                        @Override
                        public boolean onCancel(DialogInterface dialog, int keyCode, KeyEvent event) {
                            LogUtil.i("=====我拦截了返回键=====");
                            ToastUtil.shortShow("=====我拦截了返回键=====");
                            return true;//此处需要返回true才会拦截返回键事件
                        }
                    })
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    运行效果如下


    5.gif

    八. 其他方法

        /**设置点击屏幕外面是否关闭dialog**/
        public AppDialogFragment setCancelOnTouchOutside(boolean canDismiss)
    
        /**dialog是否已经显示**/
        isShowing()
    
        /***
         * 显示dialog,需要传 fragmentManager=getSupportFragmentManager()
         * @param fragmentManager
         */
        public void showDialog(FragmentManager fragmentManager)
    
        /**用于子类在使用时创建DialogFragment对象**/
        createFragment(Class<?>cls,Context context,OnCreateFragmentListener listener)
    
        /**获取editText的值**/
        getTextOfView(TextView textView)
    

    九. 一个dialog调用的通常基本设置

    继承AppDialogFragment建的dialog拥有众多方法,但在一般情况使用的时候,只需要做些基本设置,以NormalDialg为例,一些基本设置如下

            new NormalDialog()
    //                .setRidShadow(true)//当dialog设置圆角背景的时候,会留下边角阴影,设置true的时候,可去除边角,默认为false,即有边角阴影
                    .setUIShadow(false)//默认弹出diaolog时,界面无遮罩
                    .setCancel(true)//返回键是否关闭dialog,默认true
                    .setCancelOnTouchOutside(true)//屏幕外点击是否关闭,默认true
                    .showDialog(getSupportFragmentManager());//显示dialog
    

    十. AppDialogFragment源码

    下面给出AppDialogFragment源码:

    相关文章

      网友评论

        本文标题:Fragment(15)——通用dialog扩展使用

        本文链接:https://www.haomeiwen.com/subject/fcaryctx.html