我正在尝试为运行Android 2.3.4的一个特殊设备编写一个应用程序,它将系统覆盖放置在屏幕上精确定义的位置。这就是我使用绝对值定位图层的原因。
我写了一个活动(包括布局中的两个按钮),用于启动和停止显示此叠加层的服务。
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void showOverlay(View view) {
Intent i = new Intent("myPackage.myService");
startService(i);
}
public void hideOverlay(View view) {
Intent i = new Intent("myPackage.myService");
stopService(i);
}
}
这是我的服务(也被添加到清单文件中)。
public class MyService extends Service {
ImageView iv;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
int imageRes = 0;
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.NO_GRAVITY;
params.alpha = 1;
switch (findRotation()) {
case Surface.ROTATION_0:
params.height = 12; params.width = 600; params.x = 0; params.y = 1012;
imageRes = R.drawable.horizontal;
break;
case Surface.ROTATION_180:
params.height = 12; params.width = 600; params.x = 0; params.y = 0;
imageRes = R.drawable.horizontal;
break;
case Surface.ROTATION_90:
params.height = 600; params.width = 12; params.x = 1012; params.y = 0;
imageRes = R.drawable.vertical;
break;
case Surface.ROTATION_270:
params.height = 600; params.width = 12; params.x = 0; params.y = 0;
imageRes = R.drawable.vertical;
break;
}
final WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
iv = new ImageView(getApplicationContext());
iv.setClickable(false);
iv.setImageResource(imageRes);
iv.draw(new android.graphics.Canvas());
wm.addView(iv, params);
}
private int findRotation() {
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
return display.getRotation();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onDestroy(); //I don't know how to to make the service reposition the layer, so I used this. Not nice but it works
onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
if(iv != null) {
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(iv);
iv = null;
}
}
}
要显示为叠加层的图像有我的设备屏幕的宽度(或高度,我没有找到在API级别10旋转drawabled的方法,因此我使用了两个图像,一个用于水平显示,一个用于垂直)纵向模式下的分辨率(= 600)和12像素的高度(或宽度)。我希望它被定位在硬件按钮的位置,即在底部的纵向模式,当在右侧逆时针旋转90°,在顶部旋转180°时,依此类推。
适用于0°和90°(ccw)的旋转,但对于其他两个方向,图像显示在屏幕中间而不是顶部或左侧。我做错了什么?
编辑2012-04-19: 我已将params.y的值更改为ROTATION_180到-1012,此案例现在有效。不过,我不认为这是预期的行为。 ROTATION_270的类似更改无效......
答案 0 :(得分:0)
我认为当您的设备旋转180°时,它会认为它处于纵向模式,因此旋转0°。因此尝试使用相同的参数0和180,以及90和270。 我不确定,也许我错了;)。
答案 1 :(得分:0)
好的,对不起,我在更改ROTATION_270的参数时犯了错误,当我编辑我的编辑时。
我得到了我想要的代码,这就是我所做的:
我将y-param改为180°到-1012,将x-param改为270°到-1012。现在,在所有四个方向上,图像显示在硬件按钮所在的位置。
我在这里写下来只是为了完整。
(...)
switch (findRotation()) {
case Surface.ROTATION_0:
params.height = 12; params.width = 600; params.x = 0; params.y = 1012;
imageRes = R.drawable.horizontal;
break;
case Surface.ROTATION_180:
params.height = 12; params.width = 600; params.x = 0; params.y = -1012;
imageRes = R.drawable.horizontal;
break;
case Surface.ROTATION_90:
params.height = 600; params.width = 12; params.x = 1012; params.y = 0;
imageRes = R.drawable.vertical;
break;
case Surface.ROTATION_270:
params.height = 600; params.width = 12; params.x = -1012; params.y = 0;
imageRes = R.drawable.vertical;
break;
}
(...)