从onPause返回时布局显示错误

时间:2012-07-26 03:05:45

标签: android glsurfaceview

我的布局包含一个占据整个屏幕的GLSurfaceView。在屏幕的底部,我有一个半透明的工具栏(LinearLayout),它覆盖了GLSurfaceView。 此外,我的应用是全屏(android:theme="@android:style/Theme.NoTitleBar.Fullscreen)。

通常,一切都很好,但从ICS开始,每当用户回到应用程序(从onPause返回)时,操作系统都会播放一个快速动画,其中应用程序以Android状态栏显示顶部和应用程序屏幕下推。然后状态栏消失,应用程序的屏幕向上移动那么多,以达到正常的全屏位置。

当此动画完成时,GLSurfaceView最终覆盖工具栏的上半部分,工具栏覆盖GLSurfaceView的下半部分。看起来底部显示的工具栏部分与Android状态栏的大小完全相同。

当然,我希望工具栏能够完全显示和覆盖GLSurfaceView,这是从onCreate一直启动应用程序时发生的情况。

有人知道导致此问题的原因以及解决方法吗?

我找到了一个解决方法,但它远非最佳。 我可以通过在调用invalidate()后的某个时间将onResume()发布到工具栏来正确显示工具栏。但如果调用invalidate()太快,问题就不会得到解决。 以下是invalidate()之后5秒钟调用onResume()的变通方法的代码,导致工具栏在应用重启后5秒正确显示。

@Override
protected void onResume() {
    super.onResume();    

    mGLSurfaceView.onResume();

    // Test to try to fix half hidden toolbar problem
    View toolBar = findViewById(R.id.menu_bar);
    toolBar.postDelayed(new Runnable() {
        @Override
        public void run() {
            View toolBar = findViewById(R.id.menu_bar);
            toolBar.invalidate();
        }
    }, 5000);
}

修改 上面的代码不会导致工具栏正确显示。我在上面的代码中的调试TextView中取出了一个行设置文本,但事实证明,如果我不更新完全不相关的TextView,工具栏就不显示了!

我找到了另一种方法,可以通过在调用onResume时删除工具栏并稍后将其恢复原状来使上述不良解决方法工作。请参阅以下代码: 请注意,使用View.INVISIBLE代替View.GONE不会在延迟后显示工具栏。

@Override
protected void onResume() {
    super.onResume();    

    mGLSurfaceView.onResume();

    // Test to try to fix half hidden toolbar problem
    View toolBar = findViewById(R.id.menu_bar);
    toolBar.setVisibility(View.GONE);
    toolBar.postDelayed(new Runnable() {
        @Override
        public void run() {
            View toolBar = findViewById(R.id.menu_bar);
            toolBar.setVisibility(View.VISIBLE);
            //mDebugText.setText("Menu bar to front.\n" + mDebugText.getText());
        }
    }, 5000);
}

2 个答案:

答案 0 :(得分:0)

最后,这就是我解决这个问题的方法。如果有人有更好的解决方案,请务必在此处写下来,我会选择你的答案作为最佳答案。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    // Delay for the layout request. It must be longer than the time ICS takes to play
    // the animation where the app's screen moves up to fill the space of the Android
    // status bar.
    final int DELAY_MS = 1000; // in ms

    if (hasFocus) {
        // Send a delayed layout request to fix the problem with the toolbar
        // being half hidden after returning from onPause() on some devices 
        // with ICS.
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                findViewById(R.id.menu_bar).requestLayout();
            }
        }, DELAY_MS);
    }
}

首先,我将代码放在onWindowFocusChanged()中,因为当关闭屏幕时,在屏幕重新打开后(屏幕解锁之前)立即调用onResume(),因此可运行的是在实际显示应用程序之前执行,因此,在显示动画之前,所以在这种情况下问题仍然存在。

其次,我将延迟时间设为1秒,因为500毫秒太短了。动画没有完成播放,工具栏仍然隐藏了一半。当然,这会导致工具栏显示为半隐藏几毫秒,然后再将其放回正确的位置。

答案 1 :(得分:0)

我发现了有关此问题的更多详细信息以及更好的解决方法,因此这是新信息。

首先,我发现问题只发生在我使用三星的AdHubView类显示广告时,该类派生自RelativeLayout,因此问题可能与{{1}有关,也可能与此无关}。

此广告视图包含在同一顶部RelativeLayout中,其中还包含FrameLayout和工具栏(GLSurfaceView)。由于我使用LinearLayout作为布局的顶部元素,因此未明确声明此顶级FrameLayout

现在关于更好的解决方法,我所做的是隐藏<merge >中的AdHubView并在onPause中再次显示。我也尝试在onWindowFocusChanged中再次显示它,但是在关闭屏幕并且我必须解锁屏幕以返回应用程序的情况下这不起作用。

以下是一些代码示例:

onResume

通过这种解决方法,我不需要等到将工具栏强制到顶部,就像我在之前的解决方法中所做的那样,所以用户从来没有注意到任何奇怪的东西。