2

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

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

当这个动画完成时,GLSurfaceView 最终覆盖了工具栏的上半部分,工具栏覆盖了 GLSurfaceView 的下半部分。看起来底部显示的工具栏部分正是 Android 状态栏的大小。

当然,我希望工具栏完全显示和覆盖 GLSurfaceView,这就是当应用程序从onCreate.

任何人都知道是什么导致了这个问题以及如何解决它?

我找到了一种解决方法,但远非最佳。我可以通过在调用invalidate()后的某个时间发布到工具栏来正确显示工具栏。onResume()但是如果invalidate()调用太快,问题就不会得到解决。这是解决方法的代码invalidate()5 seconds after 调用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);
}
4

2 回答 2

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 毫秒太短了。动画未播放完毕,工具栏仍处于半隐藏状态。当然,这会导致工具栏在被放回其正确位置之前显示为半隐藏几毫秒。

于 2012-07-31T02:09:25.873 回答
0

我找到了有关此问题的更多详细信息和更好的解决方法,因此这是新信息。

首先,我发现问题只发生在我使用三星的AdHubView类展示广告时,该类派生自RelativeLayout,因此问题可能与RelativeLayout.

此广告视图包含在同一顶部FrameLayout,其中还包括GLSurfaceView和工具栏 ( LinearLayout)。这个顶部FrameLayout没有明确声明,因为我用作<merge >布局的顶部元素。

现在关于更好的解决方法,我所做的是将其隐藏并再次显示AdHubView在. 我也尝试再次显示它,但在屏幕关闭的情况下不起作用,我必须解锁屏幕才能返回应用程序。onPauseonWindowFocusChangedonResume

以下是一些代码示例:

protected void onPause() {
    super.onPause();

    mAdView.setVisibility(AdHubView.GONE);
}

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

    if (hasFocus) {
        mAdView.setVisibility(AdHubView.VISIBLE);
    }
}

有了这个解决方法,我不需要再强制工具栏到顶部之前等待,就像我在以前的解决方法中所做的那样,所以用户永远不会注意到任何奇怪的事情。

于 2012-08-09T08:35:37.213 回答