【问题标题】:onSurfaceCreated() called every time orientation changes每次方向改变时调用 onSurfaceCreated()
【发布时间】:2013-09-28 12:42:44
【问题描述】:

我正在像这样实现 GLSurfaceView.Renderer:

public class GL20Renderer implements GLSurfaceView.Renderer {
    private static GL20Renderer mInstance = new GL20Renderer();
    private GL20Renderer() {}
    public static GL20Renderer getInstance() {
        return mInstance;
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        Log.e("App", "onDrawFrame()");
    }
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        Log.e("App", "onSurfaceChanged()");
    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        Log.e("App", "onSurfaceCreated()");
    }

}

这个类在MainActivity中实现:

public class MainActivity extends Activity {
    private GLSurfaceView mGLView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // Create a GLSurfaceView instance and set it as the ContentView for this Activity
        mGLView = new GL20SurfaceView(this);
        setContentView(mGLView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLView.onPause();
    }

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

}

GL20SurfaceView 是:

public class GL20SurfaceView extends GLSurfaceView {
    public GL20SurfaceView(Context context) {
        super(context);

        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(GL20Renderer.getInstance());
    }
}

如您所见,非常简单。 当我现在启动应用程序时,正确调用了 onSurfaceCreated() 方法,然后调用了一次 onSurfaceChanged()。

现在的问题是:每当设备方向发生变化时,我会再次调用 onSurfaceCreated(),然后调用 onSurfaceChanged()

据我了解,每当需要创建新表面时,都会调用 onSurfaceCreated() 方法。我的问题是:为什么每当我改变设备方向时它会这样做?仅触发 onSurfaceChanged() 调用以调整视口不就足够了吗?

请注意,更改方向时我不会让设备进入睡眠状态。

【问题讨论】:

  • 当方向改变时,默认情况下会重新创建活动。如果您想停止重新加载活动,您需要在 manifest.xml 文件中指定“configChanges”属性

标签: android opengl-es orientation


【解决方案1】:

这样做

<activity
            android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            />

【讨论】:

【解决方案2】:

您绘制的 OpenGL 的优点之一是关于屏幕大小。它使您能够处理所有 Android 分辨率。

我不确定它如何与 GL20 一起工作(肯定和 GL10 一样)。

据我所知,onSurfaceChanged 提供了多种基于屏幕长度/宽度的 OpenGL 配置。

例如glViewport

GL 视图尺寸修改时需要调用glViewport 处理程序。

只有当你有宽度 = 高度是不必要的,但它是另一回事。

作为例子

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    // prevent 0 divide
    if(height == 0) {
        height=1;
    }

    screenWidth = width;
    screenHeight = height;
    ratio = (float) width/height;
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrthof(0, width, 0, height, -10f, 10f);
    gl.glViewport(0, 0, screenWidth, screenHeight);

如果您想避免这种情况,请添加到 Manifest.xml:

<activity android:name="Activity"
  android:configChanges="screenSize|orientation">

【讨论】:

  • 感谢您的快速回复。当我在onSurfaceChanged 部分添加glViewport 时,我遇到了同样的问题。 manifest.xml 修改有什么作用?
  • 看看我发布的例子,最后一行......如果你想禁用旋转屏幕更改添加到你的活动android:configChanges="screenSize|orientation
  • Manifest.xml 的更改足以让奇迹发生:它现在可以工作了!对为什么会这样的正确解释是什么?配置更改是否告诉应用程序我想监听方向更改,否则将无法正确处理?
  • 在您的清单更改后,您不会收到onSurfaceChanged 电话,对吧? developer.android.com/guide/topics/manifest/…
  • 你的意思可能是onSurfaceCreated?您对 Manifest 的更改使我解决了问题。现在我只在改变方向时得到onSurfaceChanged(这是预期的行为)。我会接受你的回答,因为它正确地解决了我的问题。深入挖掘:据我了解,Android 会选择与设备匹配的配置。每次此配置更改时,都会触发对onSurfaceCreated 的调用。请注意,在我添加清单更改之前,方向更改正在起作用。它只是触发了对onSurfaceCreated 的不必要调用
猜你喜欢
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
相关资源
最近更新 更多