问题的由来
要实现暗色的背景。通常是以下代码来实现:
window = ((Activity) context).getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.alpha = 0.5f;
window.setAttributes(params);
这段代码的含义是:获取当前activity的widow,将window的透明度更改为50%,在通常情况下使用是没有问题的。popupwindow其实就是附着在window上的我们看一下源码:
private void invokePopup(WindowManager.LayoutParams p) {
if (mContext != null) {
p.packageName = mContext.getPackageName();
}
final PopupDecorView decorView = mDecorView;
decorView.setFitsSystemWindows(mLayoutInsetDecor);
setLayoutDirectionFromAnchor();
mWindowManager.addView(decorView, p);
if (mEnterTransition != null) {
decorView.requestEnterTransition(mEnterTransition);
}
}
但是我们项目中使用了Swipelayout侧滑功能,在Style中设置了
<item name="android:windowIsTranslucent">true</item>
这样就是把你的Window设置成透明的,我们知道Window是有背景的,但是如果你想透过一个Window看另一个Window(比如看被覆盖的Activity)只设置Window的背景为透明是不行的,你还需要将Window设置成透明的,否则将会看到Window的黑底。因此要加上上面的
windowIsTranslucent设置为true.但是这样一来就使我们使用popupwindow设置的灰色背景时window的颜色就失效了。
解决方案
既然知道了原因,我们可以在poupwindow显示的时候,关掉透明背景。然而令人崩溃的是通过window设置background并不起任何作用。当然诞生了另一种解决思路,改变dim属性。dim,其中0代表透明,1代表全黑
以下代码在show的时候dim为1f,dismmiss设置为0f。
window = ((Activity) context).getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.dim = 1f;
window.setAttributes(params);
但是在我尝试的过程中设置了dim和alpha,会在第一次popshow的过程中,底层的activity还会闪一下,有个动画渐变的过程。以后再次点击均不会出现。可以采用以下方式直接在popupwindow显示的时候将activity设置为不透明,dismiss的时候设置为透明
public class LiPopActivityUtil {
/**
* 将Activity 改为不透明
*/
public static void convertFromTranslucent(Activity activity) {
if (activity.isTaskRoot()) return;//栈底Activity不处理
try {
Method convertFromTranslucent = Activity.class.getDeclaredMethod("convertFromTranslucent");
convertFromTranslucent.setAccessible(true);
convertFromTranslucent.invoke(activity);
} catch (Throwable t) {
}
}
/**
* 将Activity 改为透明
*/
public static void convertActivityToTranslucent(Activity activity) {
if (activity.isTaskRoot()) return;//栈底Activity不处理
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
convertActivityToTranslucentAfterL(activity);
} else {
convertActivityToTranslucentBeforeL(activity);
}
}
/**
* Calling the convertToTranslucent method on platforms before Android 5.0
*/
private static void convertActivityToTranslucentBeforeL(Activity activity) {
try {
Class<?>[] classes = Activity.class.getDeclaredClasses();
Class<?> translucentConversionListenerClazz = null;
for (Class clazz : classes) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
translucentConversionListenerClazz = clazz;
}
}
Method method = Activity.class.getDeclaredMethod("convertToTranslucent",
translucentConversionListenerClazz);
method.setAccessible(true);
method.invoke(activity, new Object[]{
null
});
} catch (Throwable t) {
}
}
/**
* Calling the convertToTranslucent method on platforms after Android 5.0
*/
private static void convertActivityToTranslucentAfterL(Activity activity) {
try {
Method getActivityOptions = Activity.class.getDeclaredMethod("getActivityOptions");
getActivityOptions.setAccessible(true);
Object options = getActivityOptions.invoke(activity);
Class<?>[] classes = Activity.class.getDeclaredClasses();
Class<?> translucentConversionListenerClazz = null;
for (Class clazz : classes) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
translucentConversionListenerClazz = clazz;
}
}
Method convertToTranslucent = Activity.class.getDeclaredMethod("convertToTranslucent",
translucentConversionListenerClazz, ActivityOptions.class);
convertToTranslucent.setAccessible(true);
convertToTranslucent.invoke(activity, null, options);
} catch (Throwable t) {
}
}
}
欢迎关注我的个人公众号,我们一起交流android开发相关的知识