GLSurfaceView里面片段重新启动时不能渲染

我有一个GLSurfaceView设置和呈现预期使用GLSurfaceView.Renderer 。 我的应用程序使用Android支持包中的片段。 当我导航到一个新的片段surfaceDestroyed被调用,但是当我通过backstack回到片段GLSurfaceView将不呈现,调用requestRender不会导致onDraw调用。

我知道我需要在表面视图上调用onResumeonPause ,并从托pipe片段执行此操作,但似乎无法解决问题。 所有关于htis方法的例子都是指活动,这可能是问题吗? 如果是这样的话,你如何在片段中使用GLSurfaceView

任何洞察力非常感谢,我很高兴张贴代码,但它似乎是更多的一个普遍的问题,

谢谢

以下是我如何在片段中设置我的GLSurfaceView:

 onCreateView() { glSurfaceView = new GLSurfaceView(getActivity()); ... } onPause() { if (glSurfaceView != null) { glSurfaceView.onPause(); } ... } onResume() { if (glSurfaceView != null) { glSurfaceView.onResume(); } ... } 

}

所以,类似于你在一个活动中做什么。 这在我的用例中起作用,所以看起来好像他们在分段工作。 不知道你的代码是什么样子,很难多说。

我知道这是为时已晚,但可能对其他人有用这是我的答案,因为我已经实现了它,它在模拟器和设备,以及well.i有效使用片段和支持V4.Hope你会喜欢它。

 import android.opengl.GLSurfaceView; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.example.opengles20.glsurfaceview.GlSurfaceViewClass; import com.example.opengles20.renderer.RendererClass; public class MYGlclass extends Fragment { private GlSurfaceViewClass mGLView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { return null; } View view=inflater.inflate(R.layout.main, container, false); mGLView=(GlSurfaceViewClasss)view.findViewById(R.id.gl_surface_view); mGLView.setEGLContextClientVersion(2); RendererClass rendererclass=new RendererClass(getActivity()); mGLView.setRenderer(rendererclass); mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); return view; } } 

使用glsurfaceview使用片段时需要实现的几件事情。 它有点棘手,但留在我身边。 当你导航到一个新的片段时,ondestroyview会自动被glsurfaceview调用你的片段,这将破坏你的视图(你创build并在oncreateview中返回的glsurfaceview)。

所以,当你导航到一个新的片段然后onpause,onstop,ondestroyview被自动调用,没有任何工作的一部分。 当你回到与glsurfaceview然后oncreateview,onactivitycreate,onstart和onresume片段被自动调用,没有任何工作的部分。

您的问题的关键是了解可以在android开发人员网站find的片段生命周期,并了解如何glsurfaceview函数。

现在,使用glsurfaceview你必须实现渲染器,使用onsurfacecreated,onsurfacechanged和ondrawframe。 导航到另一个片段,然后回到你的片段与glsurfaceview将导致onsurfacecreated被再次调用,因为你的glsurfaceview在ondestroyview被销毁,你的上下文已经丢失,你需要重新加载所有的资源在gl线程。

最后,从你的问题来看,ondrawframe没有被调用,这可能是由于你不重新创build视图,设置渲染器,并从oncreateview返回你的视图。

所以在oncreateview你需要这样的东西

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View mView = inflater.inflate(R.layout.fragment_layout, null); surface = (GLSurfaceView) mView.findViewById (R.id.glsurfaceview); surface.setEGLContextClientVersion(2); //return your view here return mView; } @Override public void onActivityCreated(Bundle mState) { super.onActivityCreated(mState); //setting your renderer here causes onSurfaceCreated to be called //if you set your renderer here then you have a context to load resources surface.setRenderer( shader ); } 

你不想在onc​​reateview中创build你的渲染类(着色器),除非你希望你的渲染类每当你用glsurfaceview返回到你的片段时重新开始。 而是在你的Fragments onCreate中创build你的渲染类,这样,如果你已经设置了一些东西,那么你将从你刚刚离开的地方开始,因为只需设置渲染器就可以为你提供表面,这将导致onsurfacecreated,onsurfacechanged和ondrawframe被调用自动。 确保你重新加载你上一次使用的任何资源,在绘制之前在ondrawframe中。

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); shader = new Shader(this); Log.d("Fragment", "OnCreate"); } 

当你暂停和恢复你的片段时,在大多数情况下,当你dynamicreplace一个片段并将其添加到堆栈中时,会自动处理这个片段,所以只需将surface.onpause()和surface.onResume()放在正确的位置你很好走。

为了让事情变得清晰,可以尝试在围绕片段生命周期和glsurfaceview渲染器的方法中放置日志语句,您将能够看到现在和未发生的事情。

我不用碎片工作,但如果glsurface被破坏了,也许不得不再次创build一个OpenGLRenderer的实例,并向glsurface反映,这个代码在改变方向和重新创build所有屏幕的时候为我工作,在这种情况下,我必须再次设置布局的contentview重置glsurfaceview:

 view.onPause(); setContentView(R.layout.slidegl); view = (GLSurfaceView) this.findViewById(R.id.glSurface); renderer = new OpenGLRenderer(); view.setRenderer(renderer); view.onResume(); 

如果您不想重新启动并设置所有的视图内容,请尝试创buildGLSurface的新对象:

 this.view = new GLSurfaceView(); 

我不是OpenGL ES的专家,但是我已经足够围绕碎片及其生命周期奋斗了。 我build议你做的是为你的片段设置onCreateView ,告诉渲染器再次开始绘制,如果这不起作用,尝试从片段的onResume做。 当涉及在片段中绘制GL表面时,不应该从活动级别做任何事情。