Android 如何在方向更改后使全屏覆盖保持全屏?
我正在制作一个应用程序,它可以在你的屏幕上创建小精灵动画 我有一个主要活动,有一个按钮“启动服务”。这将启动一个服务,该服务(在Android 如何在方向更改后使全屏覆盖保持全屏?,android,android-layout,android-service,android-view,android-fullscreen,Android,Android Layout,Android Service,Android View,Android Fullscreen,我正在制作一个应用程序,它可以在你的屏幕上创建小精灵动画 我有一个主要活动,有一个按钮“启动服务”。这将启动一个服务,该服务(在onCreate()中)创建一个全屏视图并将其附加到根窗口管理器 这部分工作得很好。它充满了屏幕,你可以离开应用程序,动画仍然可以在任何地方看到 旋转设备时会出现问题 精灵已经移到屏幕中间,但这是一个无关的问题;这里最重要的是黑暗的边界框-这个框显示了我可以画的画布,它需要填充整个屏幕 视图仍然是纵向模式,即使所有其他布局似乎已正确更新 部分问题来自于我如何指定视
onCreate()
中)创建一个全屏视图并将其附加到根窗口管理器
这部分工作得很好。它充满了屏幕,你可以离开应用程序,动画仍然可以在任何地方看到
旋转设备时会出现问题
精灵已经移到屏幕中间,但这是一个无关的问题;这里最重要的是黑暗的边界框-这个框显示了我可以画的画布,它需要填充整个屏幕
视图仍然是纵向模式,即使所有其他布局似乎已正确更新
部分问题来自于我如何指定视图的维度。我使用标志来指定“全屏”,但这并没有设置视图的
宽度和高度
,以匹配屏幕的尺寸。因此,我必须在启动时手动设置
我不知道创建视图后如何更新视图的宽度和高度,但我觉得我需要这样做,因为视图的尺寸决定画布的尺寸
我的服务创建如下视图:
公共类WalkerService扩展服务{
私人WalkerView视图;
@凌驾
public void onCreate(){
super.onCreate();
最终WindowManager wm=(WindowManager)getSystemService(窗口服务);
最终DisplayMetrics=新的DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
view=newwalkerview(this);//扩展SurfaceView
final WindowManager.LayoutParams params=新建WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_全屏显示,
WindowManager.LayoutParams.FLAG_全屏显示,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,//apiLevel>=19中的TYPE_SYSTEM_警报被拒绝
WindowManager.LayoutParams.FLAG_布局在屏幕中,
像素格式。半透明
);
view.setFitsSystemWindows(false);//允许我们在状态栏、导航栏上绘制
//这里我手动设置尺寸,否则它默认为正方形(类似1024x1024)
params.width=metrics.widthPixels;
params.height=metrics.height像素;
wm.addView(视图,参数);
}
}
我尝试了倾听方向的变化,并在发生变化时旋转视图:
@覆盖
公共无效OnConfiguration已更改(配置newConfig){
super.onConfigurationChanged(newConfig);
view.setRotation(
newConfig.orientation==Configuration.orientation\u
?90.0f
:0.0f
);
}
但是setRotation()
似乎并没有影响我视图的宽度和高度,也没有改变画布渲染的角度
我根本上误解了如何创建全屏覆盖吗?我如何保持在整个屏幕上画图的能力,而不考虑方向(甚至当我的应用程序不是活动应用程序时)
也许这与我将视图附加到窗口服务的窗口管理器这一事实有关——也许这意味着我的视图有一个奇怪的父视图(我可以想象,根视图可能不受方向的影响,或者没有定义的边界供子视图拉伸填充)
完整的源代码,以防我在这里遗漏了任何有用的信息
WalkerView.java
可能特别相关,因此。我认为您的情况可以用另一种方法解决
创建全屏自定义视图(您可以在自定义视图的构造函数中设置适当的标志)
在自定义视图中重写onSizeChanged()
。这将为您提供画布的高度和宽度。这是可选的。如果要使用半透明颜色填充整个自定义视图,则不需要这样做
从上方使用宽度和高度,或者在自定义视图的onDraw()
中使用canvas.drawColor()
这将确保每当重新创建视图时,视图都会被重新绘制以填充整个屏幕(画布)。我被前面问题的答案误导了。也许它适用于较旧的API级别?我使用的是API级别24
该具体答复建议:
final WindowManager.LayoutParams params=new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_全屏显示,
WindowManager.LayoutParams.FLAG_全屏显示,
WindowManager.LayoutParams.TYPE\系统\警报,
WindowManager.LayoutParams.FLAG_布局在屏幕中,
像素格式。半透明
);
这有一个问题。WindowManager.LayoutParams的构造函数如下所示:
因此,WindowManager.LayoutParams.FLAG_全屏
标志被用作int w
和int h
的显式值。这不好
我发现全屏覆盖的正确结构如下:
final WindowManager.LayoutParams params=new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,//apiLevel>=19中的TYPE_SYSTEM_警报被拒绝
WindowManager.LayoutParams.FLAG_布局_在| WindowManager.LayoutParams.FLAG_全屏显示,
像素格式。半透明
);
这意味着我们不再明确指定宽度和高度。布局完全依赖于我们的旗帜
是,WindowManager.LayoutParams.FLAG\u LAYOUT\u IN\u SCREEN
仍然是必需的标志;如果你想提取12月份的存款,这是必要的