最近在项目中遇到一个多窗口情况下切换主题,两个界面主题切换速度不一样的情况,
如下图所示:打开一个小窗口,将设置运行在窗口下,在窗口下随便再打开一个应用。这种情况下切主题,会出现两个窗口主题切换速度不同步。
解决方案是在按下主题切换的按钮时,先截取当前屏幕,然后讲图片先铺在屏幕最上方,然后在背后切换主题,当主题切换完成之后再讲图片撤掉。
如下在按下按钮之后先去截屏,截屏之后创建一个弹窗,弹窗是一个全屏的,将截屏图片设置给弹窗背景,
this.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//先去截屏,
Bitmap bitmap = ScreenShortHelper.getInstence(MainActivity.this).captureScreenshot();
Log.e(TAG, "Bitmap: "+bitmap);
//转成Drawable
BitmapDrawable drawable= new BitmapDrawable(bitmap);
dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.dialog_test_fullscreen);
//给弹窗设置一个很高的层级。 TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;
dialog.getWindow().setType(2018);
dialog.show();
//将Drawable设置给Dialog的背景
dialog.getWindow().setBackgroundDrawable(drawable);
//设置Dialog为全屏
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//切换主题颜色
mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
//延迟1秒将弹窗消失掉。
handler.sendEmptyMessageDelayed(1, 1000);
Log.e(TAG, "onClick:UiModeManager.MODE_NIGHT_YES");
}
});
如下是截屏代码
@SuppressLint("NewApi")
public Bitmap captureScreenshot() {
DisplayMetrics displayMetrics = new DisplayMetrics();
Rect crop = new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
mDisplayManager =context.getSystemService(DisplayManager.class);
int width = crop.width();
int height = crop.height();
Bitmap screenshot = null;
final Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
final DisplayAddress address = display.getAddress();
if (!(address instanceof DisplayAddress.Physical)) {
Log.e(TAG, "Skipping Screenshot - Default display does not have a physical address: "
+ display);
} else {
final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address;
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
physicalAddress.getPhysicalDisplayId());
final SurfaceControl.DisplayCaptureArgs captureArgs =
new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
.setSourceCrop(crop)
.setSize(width, height)
.build();
final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
SurfaceControl.captureDisplay(captureArgs);
screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
}
return screenshot;
}
截屏的代码是系统@hide的api,代码要跟着系统源码进行编译。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/src/main/res
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PROGUARD_FLAG_FILES := proguard-rules.pro
LOCAL_MANIFEST_FILE := src/main/AndroidManifest.xml
LOCAL_STATIC_JAVA_LIBRARIES += androidx.appcompat_appcompat
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PACKAGE_NAME := MyApplication
include $(BUILD_PACKAGE)
代码下载路径: