PopupWindow 在 Android N(7.0) 的兼容性問題

轉(zhuǎn)載 http://www.itdecent.cn/p/0df10893bf5b,并在此基礎(chǔ)上完善了下

packagecn.kidyn.qdmedical160.view;

importandroid.content.Context;

importandroid.os.Build;

importandroid.text.TextUtils;

importandroid.util.AttributeSet;

importandroid.view.Gravity;

importandroid.view.View;

importandroid.view.WindowManager;

importandroid.widget.PopupWindow;

importjava.lang.reflect.Field;

importjava.lang.reflect.Method;

/**

* Fix 7.0 showLocation,showAsDropDown兼容問題

* Created by qulj on 2017/4/10.

*/

public classFixedPopupWindowextendsPopupWindow{

publicFixedPopupWindow(Contextcontext) {

super(context);

}

publicFixedPopupWindow(Contextcontext,AttributeSetattrs) {

super(context,attrs);

}

publicFixedPopupWindow(Contextcontext,AttributeSetattrs,intdefStyle) {

super(context,attrs,defStyle);

}

publicFixedPopupWindow(Contextcontext,AttributeSetattrs,intdefStyleAttr,intdefStyleRes) {

super(context,attrs,defStyleAttr,defStyleRes);

}

publicFixedPopupWindow(ViewcontentView) {

super(contentView);

}

publicFixedPopupWindow() {

super();

}

publicFixedPopupWindow(intwidth,intheight) {

super(width,height);

}

publicFixedPopupWindow(ViewcontentView,intwidth,intheight,booleanfocusable) {

super(contentView,width,height,focusable);

}

publicFixedPopupWindow(ViewcontentView,intwidth,intheight) {

super(contentView,width,height);

}

@Override

public voidupdate(intx,inty,intwidth,intheight,booleanforce) {

if(Build.VERSION.SDK_INT!=24) {

super.update(x,y,width,height,force);

return;

}

if(width>=0) {

setParam("mLastWidth",width);

setWidth(width);

}

if(height>=0) {

setParam("mLastHeight",height);

setHeight(height);

}

Objectobj=getParam("mContentView");

ViewmContentView=null;

if(objinstanceofView) {

mContentView= (View)obj;

}

if(!isShowing() ||mContentView==null) {

return;

}

obj=getParam("mDecorView");

ViewmDecorView=null;

if(objinstanceofView) {

mDecorView= (View)obj;

}

finalWindowManager.LayoutParamsp=

(WindowManager.LayoutParams)mDecorView.getLayoutParams();

booleanupdate=force;

obj=getParam("mWidthMode");

intmWidthMode=obj!=null? (Integer)obj:0;

obj=getParam("mLastWidth");

intmLastWidth=obj!=null? (Integer)obj:0;

final intfinalWidth=mWidthMode<0?mWidthMode:mLastWidth;

if(width!= -1&&p.width!=finalWidth) {

p.width=finalWidth;

setParam("mLastWidth",finalWidth);

update=true;

}

obj=getParam("mHeightMode");

intmHeightMode=obj!=null? (Integer)obj:0;

obj=getParam("mLastHeight");

intmLastHeight=obj!=null? (Integer)obj:0;

final intfinalHeight=mHeightMode<0?mHeightMode:mLastHeight;

if(height!= -1&&p.height!=finalHeight) {

p.height=finalHeight;

setParam("mLastHeight",finalHeight);

update=true;

}

if(p.x!=x) {

p.x=x;

update=true;

}

if(p.y!=y) {

p.y=y;

update=true;

}

//? ? ? ? obj = execMethod("computeAnimationResource");

obj=execMethod("computeAnimationResource",newClass[]{int.class},null);

final intnewAnim=obj==null?0: (Integer)obj;

if(newAnim!=p.windowAnimations) {

p.windowAnimations=newAnim;

update=true;

}

obj=execMethod("computeFlags",newClass[]{int.class},newObject[]{p.flags});

final intnewFlags=obj==null?0: (Integer)obj;

if(newFlags!=p.flags) {

p.flags=newFlags;

update=true;

}

if(update) {

execMethod("setLayoutDirectionFromAnchor",null,null);

obj=getParam("mWindowManager");

WindowManagermWindowManager=objinstanceofWindowManager? (WindowManager)obj:null;

if(mWindowManager!=null) {

mWindowManager.updateViewLayout(mDecorView,p);

}

}

}

/**

*反射獲取對象

*@paramparamName

*@return

*/

privateObject getParam(StringparamName) {

if(TextUtils.isEmpty(paramName)) {

return null;

}

try{

Fieldfield=PopupWindow.class.getDeclaredField(paramName);

field.setAccessible(true);

returnfield.get(this);

}catch(Exceptione) {

e.printStackTrace();

}

return null;

}

/**

*反射賦值對象

*@paramparamName

*@paramobj

*/

private voidsetParam(StringparamName,Objectobj) {

if(TextUtils.isEmpty(paramName)) {

return;

}

try{

Fieldfield=PopupWindow.class.getDeclaredField(paramName);

field.setAccessible(true);

field.set(this,obj);

}catch(Exceptione) {

e.printStackTrace();

}

}

/**

*反射執(zhí)行方法

*@parammethodName

*@paramargs

*@return

*/

privateObject execMethod(StringmethodName,Class[]cls,Object[]args) {

if(TextUtils.isEmpty(methodName)) {

return null;

}

try{

Methodmethod=getMethod(PopupWindow.class,methodName,cls);

method.setAccessible(true);

returnmethod.invoke(this,args);

}catch(Exceptione) {

e.printStackTrace();

}

return null;

}

/**

*利用遞歸找一個(gè)類的指定方法,如果找不到,去父親里面找直到最上層Object對象為止。

*

*@paramclazz

*目標(biāo)類

*@parammethodName

*方法名

*@paramclasses

*方法參數(shù)類型數(shù)組

*@return方法對象

*@throwsException

*/

privateMethod getMethod(Classclazz,StringmethodName,

finalClass[]classes)throwsException{

Methodmethod=null;

try{

method=clazz.getDeclaredMethod(methodName,classes);

}catch(NoSuchMethodExceptione) {

try{

method=clazz.getMethod(methodName,classes);

}catch(NoSuchMethodExceptionex) {

if(clazz.getSuperclass() ==null) {

returnmethod;

}else{

method=getMethod(clazz.getSuperclass(),methodName,

classes);

}

}

}

returnmethod;

}

@Override

public voidshowAsDropDown(ViewanchorView) {

if(Build.VERSION.SDK_INT==24) {

int[]a=new int[2];

anchorView.getLocationInWindow(a);

showAtLocation(anchorView,Gravity.NO_GRAVITY,0,a[1] +anchorView.getHeight() +0);

}else{

super.showAsDropDown(anchorView);

}

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容