Android自定义通用的Dialog

先来唠唠嗑

昨晚杭州迎来了2018年的第一场雪,还不错,回家之前看到雪了,去年都没看到。雪天路滑,大家注意安全,小心开车!

今天来写一篇关于自定义Dialog的文章,我们在开发中Dialog也是避免不了的,所以封装一个通用的Dialog很有必要,可以避免类的重复,减少代码冗余,我会通过封装一个Java类,然后通过填充不同样式的布局,来达到实现不同的弹出框效果。好了,天也不早了,话不多说,开始今天的表演!

一、Java类的实现(核心代码)

在这个类中,我提供了两套模板,第一套:固定宽高,弹出位置屏幕中间,这里我首先会获取屏幕的宽高,然后宽度取屏幕宽的2/3,高度取屏幕高的1/3,这个是我根据自己项目中的效果去定义的,大家可以根据自己公司的实际效果对这个比例进行修改。第二套:不固定宽高,弹出位置不固定,并且加了一个小的动画,动画资源和Dialog的统一主题我会在下面给出。代码中还有个全局变量tag,这个tag是我用来区分同一个页面中有多个不同的Dialog时作的一个标记,代码的大体描述就是这样,很简单的代码,都能看懂:

package com.jarchie.htgl.views;

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import com.jarchie.htgl.R;
import com.jarchie.htgl.utils.ScreenUtil;

/**
 * Created by Jarchie on 2017\12\20.
 * 创建通用的自定义Dialog
 */

@SuppressWarnings({"ConstantConditions", "WeakerAccess"})
public class CommonDialog extends Dialog {

    private static final int WIDTH_PERCENT = 2; //宽度比
    private static final int HEIGHT_PERCENT = 3; //高度比
    private String tag; //自定义标识

    //固定大小Dialog模板
    public CommonDialog(Context context, int layout) {
        this(context, layout, R.style.Theme_dialog, Gravity.CENTER);
    }

    //固定大小Dialog属性
    public CommonDialog(Context context, int layout, int style, int gravity) {
        super(context, style);
        //设置属性
        setContentView(layout);
        int deviceWidth = ScreenUtil.getScreenWidth();
        int deviceHeight = ScreenUtil.getScreenHeight();
        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = deviceWidth / HEIGHT_PERCENT * WIDTH_PERCENT;
        layoutParams.height = deviceHeight / HEIGHT_PERCENT;
        layoutParams.gravity = gravity;
        window.setAttributes(layoutParams);
    }

    //自定义Dialog模板
    public CommonDialog(Context context,int width,int height,int layout,int gravity){
        this(context,width,height,layout,R.style.Theme_dialog,gravity,R.style.pop_anim_style);
    }

    //自定义大小Dialog属性
    public CommonDialog(Context context,int width,int height,int layout,int style,int gravity,int animation){
        super(context,style);
        //设置属性
        setContentView(layout);
        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = width;
        layoutParams.height = height;
        layoutParams.gravity = gravity;
        window.setAttributes(layoutParams);
        window.setWindowAnimations(animation);
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

}

其中ScreenUtil类中的获取屏幕宽高的代码如下:

//获取屏幕的宽
public static int getScreenWidth() {
    final Resources resources = BaseApp.getContext().getResources();
    final DisplayMetrics dm = resources.getDisplayMetrics();
    return dm.widthPixels;
}

//获取屏幕的高
public static int getScreenHeight() {
    final Resources resources = BaseApp.getContext().getResources();
    final DisplayMetrics dm = resources.getDisplayMetrics();
    return dm.heightPixels;
}

其中BaseApp.getContext()就是自定义的Application中获取全局上下文对象的方法,这里就不再贴代码了。

接着来说说自定义的主题,代码如下:

<!-- 自定义Dialog的主题 -->
<style name="Theme_dialog" parent="@android:style/Theme.Dialog">
    <!--全透明-->
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
</style>

还有自定义的动画的style,代码如下:

<!-- 自定义Dialog动画 -->
<style name="pop_anim_style">
    <item name="android:windowEnterAnimation">@anim/pop_in</item>
    <item name="android:windowExitAnimation">@anim/pop_out</item>
</style>

其中,动画资源代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="250">
    <translate
        android:fromYDelta="-100%p"
        android:toYDelta="0" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="250">
    <translate
        android:fromYDelta="0"
        android:toYDelta="-100%p"/>
</set>

好了,编写过程就是这些,下面来看看具体使用方法。

二、举个栗子

1、先来看布局文件 dialog_alert_layout.xml,我们需要编写一个弹出框的布局文件,这个待会要用到的:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog_alert_shape"
    android:gravity="center"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tips"
        android:textColor="@color/colorPrimary"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/dialog_tip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="@color/color_333"
        android:textSize="15sp"
        android:text="@string/tips_info" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/btn_confirm"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="10dp"
            android:layout_weight="1"
            android:background="@drawable/button_bg"
            android:gravity="center"
            android:paddingBottom="5dp"
            android:paddingTop="5dp"
            android:text="@string/confirm"
            android:textColor="@color/color_white"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/btn_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:background="@drawable/button_bg"
            android:gravity="center"
            android:paddingBottom="5dp"
            android:paddingTop="5dp"
            android:text="@string/cancel"
            android:textColor="@color/color_666"
            android:textSize="14sp" />
    </LinearLayout>

</LinearLayout>

效果如下图所示:

2、然后在我们需要使用弹出框的页面中去实例化我们的这个对象,并且绑定内部的控件,做相应的动态处理,比如更改标题的文本内容、处理按钮的点击事件这些:

实例化Dialog对象:

mCommonDialog = new CommonDialog(getContext(), R.layout.dialog_alert_layout);
mCommonDialog.setCanceledOnTouchOutside(false);
mCommonDialog.setCancelable(false);

绑定内部控件:

btnConfirm = mCommonDialog.findViewById(R.id.btn_confirm);
btnCancel = mCommonDialog.findViewById(R.id.btn_cancel);

添加点击事件:

btnConfirm.setOnClickListener(this);
btnCancel.setOnClickListener(this);

处理点击事件:

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_login_out:
            mCommonDialog.show();
            break;
        case R.id.btn_confirm:
            
            break;
        case R.id.btn_cancel:
            mCommonDialog.cancel();
            break;
    }
}

可以看到这些使用方法和我们平时的普通控件的使用是完全一样的,之所以这样写就是为了灵活的去适用不同的业务场景,有时候封装好的一句话调用的控件并不一定适用于你的需求,这种方式虽然使用比那种完全方式代码要多一些,但是很灵活,当然了,你也可以基于这个类,继续接着往上层封装一个工具类,对外提供好显示隐藏处理点击事件的方法,直接调用相对应的方法也是可以的,这里就不再多讲了。
三、福利

快过年了,给大家个小福利,推荐一个高集成的快速创建对话框的库给大家,双手奉上项目地址:

https://github.com/yilylong/CBDialog
放张图吧,简单介绍:

今天的内容就这么多,谢谢各位小伙伴!

发布了48 篇原创文章 · 获赞 47 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/JArchie520/article/details/79157471