【发布时间】:2017-01-04 02:06:14
【问题描述】:
我正在制作一个应用程序,它可以创建在你的屏幕上四处走动的小精灵动画。
我有一个主要活动,带有一个“启动服务”按钮。这将启动一个服务,该服务(在onCreate() 中)创建一个全屏视图并将其附加到根窗口管理器。
这部分工作得很好。它会填满屏幕,您可以离开应用程序,动画仍然会在所有内容上可见。
旋转设备时出现问题。
精灵已经移动到屏幕中间,但这是一个无关的问题;这里重要的是黑色边界框——这个框显示了我可以在其中绘制的画布,它需要填满整个屏幕
视图仍然是纵向模式,尽管所有其他布局似乎都已正确更新。
部分问题来自我如何指定视图的尺寸。我使用标志来指定“全屏”,但这确实没有设置视图的width 和height 以匹配屏幕的尺寸。因此我不得不在启动时手动设置。
我不知道创建视图后如何更新视图的宽度和高度,但我觉得我需要这样做,因为视图的尺寸决定了画布的尺寸。
我的服务像这样创建视图:
public class WalkerService extends Service {
private WalkerView view;
@Override
public void onCreate() {
super.onCreate();
final WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
final DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
view = new WalkerView(this); // extends SurfaceView
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
view.setFitsSystemWindows(false); // allow us to draw over status bar, navigation bar
// here I _manually_ set the dimensions, because otherwise it defaults to a square (something like 1024x1024)
params.width = metrics.widthPixels;
params.height = metrics.heightPixels;
wm.addView(view, params);
}
}
我尝试过监听方向变化,并在发生这种情况时旋转视图:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
view.setRotation(
newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE
? 90.0f
: 0.0f
);
}
但是setRotation() 似乎并没有影响到我的观点width 和height,也没有改变画布的渲染角度。
我是否从根本上误解了如何创建全屏叠加层?无论方向如何(即使我的应用不是活动应用),我如何才能保持在整个屏幕上绘图的能力?
也许这与我将视图附加到窗口服务的窗口管理器这一事实有关——也许这意味着我的视图有一个奇怪的父视图(我可以想象根视图可能不会受到方向的影响,或者没有为孩子们定义的边界以伸展填充)。
完整的源代码是public on GitHub,以防我在这里省略了任何有用的信息。
WalkerView.java 可能特别相关,所以here it is。
【问题讨论】:
-
我认为这是一个重复的问题stackoverflow.com/a/10107525/5870896
-
拥有 2 个视图怎么样。一个用于纵向,一个用于横向,每个都具有正确的宽度和高度。当方向发生变化时,只需删除不相关的视图并将有效视图添加到窗口管理器。
-
@SecretCoder 我相信我的代码已经类似于该问题的答案,因为这是我用来构建代码的参考之一。唯一的区别是链接的答案通过使用充气机来获取对视图的引用,而我的代码在服务中构造了一个内联视图的实例。鉴于我有与该答案相当的代码并且仍然遇到问题:我会说链接的问题不回答我的问题,因此不 i> 同样的问题。
-
@KartikSharma 可以工作。是不是矫枉过正?理想情况下,我想避免给用户的屏幕旋转增加太多开销。我还怀疑覆盖消失的间隙会存在;我宁愿避免看起来有问题的事情。我确实有另一个想法:也许我可以让画布是方形的——两个尺寸都设置为
Math.max(metrics.widthPixels, metrics.heightPixels)。这样,同一个画布可以用于任一方向(只需要知道屏幕边界在哪里)。 -
能否请您添加完整代码?
标签: android android-layout android-service android-view android-fullscreen