目录
前言
之前写过一篇《Android自定义通用的Dialog》,最近在整理文章时看到了,发现代码其实可以简化一下,所以本篇也是写一个通用的Dialog,但是我们会对代码做进一步的封装,让我们的代码逻辑看起来更加简洁清晰,好了,话不多说,一起来动手实现吧!
一、自定义DialogView
封装思路:既然是封装Dialog,那么我们肯定是首先要考虑它的通用性,而不是每种不同的Dialog我们都要单独写一个类,在里面定义它的方法,我们尽量要做到能够统一管理,所以这里我们考虑当UI改变时,我们只去替换xml布局文件即可,对于主题样式的展示我们使用统一定义的类。再一个就是Dialog的显示位置,我们这里考虑可能不同的需求需要显示在屏幕的不同位置,所以这里我们也考虑做到动态传入。那么基于这个大致的思路,我们来写一个类继承自系统的Dialog:
import android.app.Dialog;
import android.content.Context;
import android.view.Window;
import android.view.WindowManager;
/**
* 作者:created by Jarchie
* 时间:2019-11-12 21:24:08
* 邮箱:jarchie520@gmail.com
* 说明:自定义提示框
*/
public class DialogView extends Dialog {
public DialogView(Context context,int layout, int style,int gravity) {
super(context, style);
setContentView(layout);
Window window = getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = gravity;
window.setAttributes(layoutParams);
}
}
对于它的构造参数我们不用全部都实现,因为我们需要使用它的透明主题,所以这里我使用了它的两个参数的构造方法,super是调用了它父类的构造方法,两个参数很明显context和style,然后我们根据上面最开始的思路,我们再定义我们自己需要的参数,从代码中可以看到那就是我们的layout布局文件和gravity它的显示位置,因为这里是调用了super,所以这里我们自己的参数想怎样传都是可以的,你也可以继续增加你需要的参数都是OK的,因为父类的构造参数一定是会调用的。然后下面就是对方法内部的代码做一个简要的说明,都是大家很熟悉的东西了:
setContentView(layout):传入layout设置我们的布局;
getWindow():拿到它的父容器,为下面做改变主题打基础;
window.getAttributes():拿到window对象的属性,返回的是一个LayoutParams;
layoutParams.width&layoutParams.height:设置它的宽和高,layoutParams.gravity是设置它的位置,使我们传入的参数;
window.setAttributes:把属性设置回去,这样我们的简单的自定义就完成了。
二、自定义Dialog管理类
这里我们定义了一个类用来管理我们所有的Dialog,也就是第一步中我们所创建的DialogView,所以我这里使用了单例模式进行创建,保证管理类实例唯一性。
既然是管理所有的Dialog,所以我们需要给它一些通用的方法,比如:初始化、显示隐藏等,所以我们定义几个方法:
initView():初始化Dialog,这里直接返回一个DialogView的实例,构造方法中传入的是DialogView的构造方法需要的参数,这里主题我们在values下的style文件里面定义了一个,内容也比较简单:背景透明无标题,代码如下:
<!--DialogView Theme Style-->
<style name="Theme_Dialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="windowNoTitle">true</item>
</style>
然后我们重载一个方法,给了一个默认的居中显示的位置,方便大多数情况下居中显示的需求处理,所以对于居中显示的可以直接调用我们的两个参数的构造方法即可。
show():定义显示Dialog的方法,判断是否正在显示,不是正在显示的情况下才显示。
hide():定义隐藏Dialog的方法,判断是否正在显示,正在显示的情况下才隐藏。
具体的代码如下所示:
import android.content.Context;
import android.view.Gravity;
import com.jarchie.resizeitem.R;
import com.jarchie.resizeitem.view.DialogView;
/**
* 作者:created by Jarchie
* 时间:2019-11-12 21:28:58
* 邮箱:jarchie520@gmail.com
* 说明:提示框管理类
*/
public class DialogManager {
//单例模式
private static volatile DialogManager mInstance = null;
private DialogManager() {
}
public static DialogManager getInstance() {
if (mInstance == null) {
synchronized (DialogManager.class) {
if (mInstance == null) {
mInstance = new DialogManager();
}
}
}
return mInstance;
}
public DialogView initView(Context mContext, int layout) {
return new DialogView(mContext, layout, R.style.Theme_Dialog, Gravity.CENTER);
}
public DialogView initView(Context mContext, int layout, int gravity) {
return new DialogView(mContext, layout, R.style.Theme_Dialog, gravity);
}
public void show(DialogView view){
if (view!=null){
if (!view.isShowing()){
view.show();
}
}
}
public void hide(DialogView view){
if (view !=null){
if (view.isShowing()){
view.dismiss();
}
}
}
}
三、使用
写完了上面这些呢,我们的自定义Dialog就已经写完了,那我们怎么使用它呢?其实很简单,一起来看一下!
首先我们可以在Activity中定义一个全局变量DialogView的对象,比如:
private DialogView mCodeView;
然后在需要初始化的地方进行初始化,只需要一行代码即可,传入上下文对象和自定义的布局文件:
mCodeView = DialogManager.getInstance().initView(this,R.layout.dialog_code_view_layout);
这样就初始化完成了,你就可以在需要显示或隐藏的地方通过DialogManager调用show和hide方法即可,传入我们的DialogView对象:
DialogManager.getInstance().show(mCodeView); //显示
DialogManager.getInstance().hide(mCodeView); //隐藏
如果需要对Dialog中的某个控件做事件处理,也很简单,可以先获取这个控件,然后就可以随心所欲的处理监听事件了:
TouchPictureView mPictureView = mCodeView.findViewById(R.id.mPictureView);
mPictureView.setViewResultListener(new TouchPictureView.OnViewResultListener() {
@Override
public void onResult() {
//处理手势抬起事件
}
});
四、拓展
这个拓展内容我这里只说一下是什么,代码最后我会给出,但不会放在这里,我想大家可以自己先做一下,然后再去和我的代码对比一下,每个人有每个人的写法,这个没有标准答案,只要能实现功能都是OK的。现在我来说一下这个思维拓展的内容:
基于上面封装的DialogView,制作一个加载提示框,上面图片下面文字,思考一下怎么实现?
就大致是这样一个效果,几乎所有app里面都有的一个加载提示。。。。。。
我的实现是:自定义一个类LoadingView结合DialogView再封装一层,单独具有加载功能的DialogView,布局很简单上面一个图片控件ImageView,下面一个文本控件TextView,构造方法中使用上面的方法对DialogView进行初始化,图片使用属性动画做旋转动画,注意loading开始时旋转,loading结束时停止旋转,提供默认文本及开放式设置文本的api,提供显示隐藏的api,整体逻辑就是这么多,对这块比较熟悉的童鞋可以直接略过。
夜已深,不多扰,文至此,关电脑!
哦对了,最后放个源码地址—— LoadingView 类点击查看,
因为我前几天写另一个Demo的时候用到了这几个类,所以就不再另外写Demo了,直接把另一个Demo的地址放上:Android---RecyclerView之动画(工具类)实现可展开列表 ,这个Demo中的内容也是挺值得一看的,有需要的可以把源码clone下来看一下!
晚安了,各位!好梦!