前言
在写这篇之前我说说我的感受,在之前有用到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;
}1234567891011121314151617
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);
}
}12345678910
反射获得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;
}12345678910111213141516171819
3.removepublic void removeView() { try { if (mWindowManager == null) return; if (!isAttachedToWindow(contentView)) return;
mWindowManager.removeView(contentView);
} catch (Exception e) { if (Config.IS_DEBUG_MODE) {
e.getMessage();
}
}
}123456789101112
4.回收防止window的泄露,Activity在销毁之前要调用recycle方法/**
* 回收
*/
public void recycle() {
activity = null;
mWindowManager = null;
}1234567
封装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);
}12345678910
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;
}123456789101112131415161718192021222324252627282930313233
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);
}
}123456789101112131415161718192021222324252627282930313233343536373839404142434445
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());
}
}
}
}1234567891011121314151617181920212223242526272829
5.用户点击处理/**
* 用户点击window事件
*
* @param v
*/
@Override
public void onClick(View v) { if (isCancelable) {
dismissByUser();
}
}1234567891011
6.回收防止window泄露public void recycle() { //先释放Window里面的Activity
dismissByUser(); if (myPopWindow != null) {
myPopWindow.recycle();
myPopWindow = null;
}
}12345678
接收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;
}
}1234567891011121314151617181920212223242526272829303132
总结
好,知道现在我们已经看完所有的源码了,其实很简单,就是我们拿到一块window,那么我们只要掌握其生命周期,然后我们就可以在这块window上面绘制我们想要的一切。