我将此自定义视图作为系统警报添加到WindowManager中,该视频应用作全屏覆盖,以在应用运行时阻止手机的某些部分。
当显示叠加层时,它可以很好地阻挡手机窗口全屏。现在我想支持轮换更改。
此部分也可正常使用,我在layout
layout-land
和layout-h600dp-land
中有3个布局文件,当我旋转手机时,它会更改为正确的布局。我遇到的问题是在onConfigurationChanged(Configuration newConfig)
被调用之后我再次给布局充气所有的点击监听器都消失了,所以视图中没有任何按钮对点击做出反应。当我点击按钮时,按钮的按下状态会发生变化,但是没有触发任何onClickListener。在方向改变之前,所有按钮都可以工作。我一直在使用Butterknife来减少onClicklisteners和findViewById的样板代码,但我已经将其更改为findViewById并在手动视图上添加clicklistener并没有什么区别。
现在有些代码了。该服务将视图添加到windowmanager
public class OverlayService extends Service {
public void showOverlay() {
startForeground();
mUiHandler.post(new Runnable() {
@Override
public void run() {
if (!DrivingOverlay.isShowing()) {
if (mOverlay == null) {
mOverlay = new Overlay(OverlayService.this);
mOverlay.setTag(OVERLAY_TAG);
mOverlay.setId(R.id.overlay);
}
addView(mOverlay);
}
});
}
private void addView(@NonNull final View view) {
try {
final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(view, Overlay.LAYOUT_PARAMS);
} catch (IllegalStateException error) {
Log.e(TAG, Log.getStackTraceString(error));
}
}
}
自定义视图,它是叠加层。
public class Overlay extends FrameLayout {
private static boolean sIsOverlayShowing;
public static final WindowManager.LayoutParams LAYOUT_PARAMS = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
public Overlay(Context context) {
super(context);
init(context);
}
public Overlay(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public Overlay(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public Overlay(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
protected void init(Context context) {
inflate(context, R.layout.driving_overlay, this);
if (!isInEditMode()) {
ButterKnife.bind(this);
}
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged");
init(getContext());
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setIsOverlayShowing(true);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setIsOverlayShowing(false);
}
@Override
public void onViewAttachedToWindow(View v) {
setIsOverlayShowing(true);
}
@Override
public void onViewDetachedFromWindow(View v) {
setIsOverlayShowing(false);
}
public static boolean isShowing() {
return sIsOverlayShowing;
}
public static void setIsOverlayShowing(boolean isOverlayShowing) {
sIsOverlayShowing = isOverlayShowing;
}
}
答案 0 :(得分:1)
终于明白了。
在init中调用SELECT
CAST(dbo.udf_FillField(T.col1, 100, N'X', N'R') AS nvarchar(100)) AS Col1
FROM
dbo.MyTable AS T;
会将正在膨胀到根视图的视图添加到inflate(context, R.layout.driving_overlay, this)
Overlay
,因此每次轮换都会为新布局充气并添加它到根视图所以在旋转后Overlay类有多个子视图。 OnClickListeners会将位置0的子视图按钮绑定到类中的OnClickListeners,它将显示在位置1或更高位置新膨胀的子视图。因此,在添加此检查并删除过时的视图后,OnClickListeners将再次运行。
FrameLayout
答案 1 :(得分:0)
Assuming you have not restricted the Restarting of activity due to change in
the orientation. When a device s configuration gets changed in your case
Orientation, its user interface has to be updated according to the new
configuration.
Being the primary component for interaction, it can be updated with some
attributes to handle changes. Default behavior of Activity when device gets
rotated is it gets destroyed and restarted again. This may be your issue.
To handle the rotation of activity use android:configChanges = "orientation"
attribute in manifest for your activity.