优雅自定义Dialog

来源:互联网 发布:软件测试ppt 编辑:程序博客网 时间:2024/06/09 13:06

前言

在写这篇之前我说说我的感受,在之前有用到Dialog的地方,我真的很郁闷,各种不适配,功能实现起来很是麻烦,那么当我接触到WindowManager后,我就心想,我要自己弄一套Dialog,来实现我想要的功能。其实我们的大部分提示窗口只要依附在Activity上就可以了,我们得到一块窗体后,我们就可以在窗体上进行绘制我们想要的效果。

封装WindowManager

1.初始化我们的WindowManager.LayoutParams

  /**     * 全屏模式     *     * @param context     * @param bg     */    public MyPopWindow(Activity context, int bg, int animatorModel) {        activity = context;        mBackGroundColor = bg;        mWindowManager = context.getWindowManager();        lp = new WindowManager.LayoutParams();        lp.format = PixelFormat.RGBA_8888;        //透明状态栏        lp.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;        lp.width = WindowManager.LayoutParams.MATCH_PARENT;        lp.height = WindowManager.LayoutParams.MATCH_PARENT;    }

2.添加View,这里注意不能重复添加

public void addView(View view) {        this.contentView = view;        if (mWindowManager == null) return;        //当View已经被加到Window上去了,那么就不能再加        if (isAttachedToWindow(contentView) || contentView.getParent() != null) return;        mWindowManager.addView(contentView, lp);        if (contentView instanceof WindowLayout){            ((WindowLayout)contentView).setPopWindow(this);        }    }

反射获得isAttachedToWindow的值

 /**     * 通过反射获取View是否AttachWindow     *     * @param view     */    public boolean isAttachedToWindow(View view) {        try {            Class classzz = View.class;            Field field = classzz.getDeclaredField("mAttachInfo");            field.setAccessible(true);            Object mAttach = field.get(view);            return mAttach != null;        } catch (Exception e) {            e.printStackTrace();        }        return false;    }

3.remove

public void removeView() {        try {            if (mWindowManager == null) return;            if (!isAttachedToWindow(contentView)) return;            mWindowManager.removeView(contentView);        } catch (Exception e) {            if (Config.IS_DEBUG_MODE) {                e.getMessage();            }        }    }

4.回收防止window的泄露,Activity在销毁之前要调用recycle方法

  /**     * 回收     */    public void recycle() {        activity = null;        mWindowManager = null;    }

封装DialogWindow

1.初始化构造方法

 public DialogWindow(Activity activity) {        this.context = activity;        myPopWindow = new MyPopWindow(activity);    }    public DialogWindow(Activity context, boolean isCancelable) {        this.context = context;        this.isCancelable = isCancelable;        myPopWindow = new MyPopWindow(context);    }

2.加载布局

 public DialogWindow loading() {        contentView = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.dialog_update, null);        contentView.setOnClickListener(this);        return this;    }    public DialogWindow loading(String tip) {        contentView = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.dialog_update, null);        TextView title = (TextView) contentView.findViewById(R.id.dialog_title);        title.setText(tip);        contentView.setOnClickListener(this);        return this;    }    public void setTitle(String tip) {        if (contentView == null) return;        TextView title = (TextView) contentView.findViewById(R.id.dialog_title);        title.setText(tip);        isNeedReset = true;    }    public void resetTitle() {        if (contentView == null) return;        TextView title = (TextView) contentView.findViewById(R.id.dialog_title);        title.setText(R.string.loading);        isNeedReset = false;    }    public ViewGroup loading(@LayoutRes int resId) {        contentView = (ViewGroup) LayoutInflater.from(context).inflate(resId, null);        contentView.setOnClickListener(this);        return contentView;    }

3.show方法

    /**     * 这你在show()的时候要判断当前的状态,     */    public void show() {        Logger.e("tag", isShowing + "");        if (!isShowing()) {            try {                myPopWindow.removeView();                myPopWindow.addView(contentView);                isShowing = true;            } catch (Exception e) {                if (Config.IS_DEBUG_MODE) {                    Log.e("Window", e.toString());                }            }        } else {            handler.removeMessages(WHAT);            dismissByUser();            show();        }    }    /**     *     */    public void show(String tip) {        Logger.e("tag", isShowing + "");        if (!isShowing()) {            try {                if(!StringUtil.isEmpty(tip)){                    setTitle(tip);                }                myPopWindow.addView(contentView);                isShowing = true;            } catch (Exception e) {                if (Config.IS_DEBUG_MODE) {                    Log.e("Window", e.toString());                }            }        } else {            handler.removeMessages(WHAT);            dismissByUser();            show(tip);        }    }

4.dismiss方法

  /**     * 显示,若果是网络请求的话,就延迟500ms。     */    public void dismiss() {        handler.sendEmptyMessageDelayed(WHAT, 500);    }    /**     * 用户点击,就立刻取消     */    public void dismissByUser() {        if (isShowing) {            try {                myPopWindow.removeView();//                if (softReferenceListener.get()!=null){//                    softReferenceListener.get().dialogDismiss();//                }                if (isNeedReset){                    resetTitle();                }                isShowing = false;            } catch (Exception e) {                if (Config.IS_DEBUG_MODE) {                    Log.e("Window", e.toString());                }            }        }    }

5.用户点击处理

    /**     * 用户点击window事件     *     * @param v     */    @Override    public void onClick(View v) {        if (isCancelable) {            dismissByUser();        }    }

6.回收防止window泄露

 public void recycle() {        //先释放Window里面的Activity        dismissByUser();        if (myPopWindow != null) {            myPopWindow.recycle();            myPopWindow = null;        }    }

接收back事件

/** * 创建日期:2017/4/20 9:45 * * @author yzz */public class WindowLayout extends RelativeLayout {    private MyPopWindow popWindow;    public WindowLayout(Context context) {        super(context);    }    public WindowLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }    public WindowLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean dispatchKeyEvent(KeyEvent event) {        if (event.getKeyCode()==KeyEvent.KEYCODE_BACK){            if (popWindow!=null)popWindow.removeView();        }        return super.dispatchKeyEvent(event);    }    public void setPopWindow(MyPopWindow popWindow) {        this.popWindow = popWindow;    }}

总结

好,知道现在我们已经看完所有的源码了,其实很简单,就是我们拿到一块window,那么我们只要掌握其生命周期,然后我们就可以在这块window上面绘制我们想要的一切。好了源码由于一些原因就不上传github了,有需要的可以联系我。

1 0
原创粉丝点击