GLSurfaceView внутри фрагмента не отображается при перезапуске

У меня есть настройка и рендеринг GLSurfaceView.Renderer как и ожидалось, с помощью GLSurfaceView.Renderer . Мое приложение использует фрагменты из пакета поддержки Android. Когда я surfaceDestroyed к новому фрагменту surfaceDestroyed вызывается, но когда я возвращаюсь к фрагменту через backstack, GLSurfaceView не будет отображаться, вызовы requestRender не приводят к вызову onDraw .

Я знаю, что мне нужно вызвать onResume и onPause на поверхностном представлении, и я делаю это из фрагмента хостинга, но он, похоже, не решает проблему. Все примеры о методе htis относятся к деятельности, может ли это быть проблемой? И если да, то как вы используете GLSurfaceView внутри фрагмента.

Любое понимание очень ценится, я рад опубликовать код, но, похоже, это более общий вопрос для меня,

благодаря

Вот как у меня есть настройка GLSurfaceView в фрагменте:

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

}

Итак, похоже на то, что вы делаете в своей деятельности. Это работает в моем случае использования, поэтому кажется, что они работают в фрагментах. Трудно сказать больше, не зная, как выглядит ваш код.

Я знаю, что слишком поздно, но может быть полезно для других. Это мой ответ, поскольку я уже реализовал его, и он хорошо работает как в эмуляторе, так и в устройстве. У меня есть фрагмент и поддержка. Надеюсь, вам понравится.

 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, что разрушает ваше представление (glsurfaceview, созданное вами и возвращаемое в oncreateview).

Поэтому, когда вы переходите к новому фрагменту, тогда onpause, onstop, ondestroyview вызывается автоматически, без какой-либо работы с вашей стороны. Когда вы возвращаетесь к этому фрагменту с glsurfaceview, тогда oncreateview, onactivitycreated, onstart и onresume автоматически вызываются, без какой-либо работы с вашей стороны.

Ключом к вашему вопросу является понимание жизненного цикла фрагмента, который можно найти на веб-сайте разработчика Android, и понимание того, как работает glsurfaceview.

Теперь, используя glsurfaceview, вы должны реализовать средство визуализации, используя onsurfacecreated, onsurfacechanged и ondrawframe. Переход к другому фрагменту, а затем возврат к вашему фрагменту с помощью glsurfaceview приведет к тому, что функция onsurfacecreated будет вызвана снова, так как ваше glsurfaceview было уничтожено в ondestroyview, ваш контекст был потерян, и вам нужно перезагрузить все ваши ресурсы в потоке gl.

Наконец, из вашего вопроса видно, что ondrawframe не вызывается, что, вероятно, связано с тем, что вы не воссоздаете свое представление, не устанавливаете средство визуализации и не возвращаете свое представление из 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 ); } 

Вы не хотите создавать свой класс рендеринга (shader) в oncreateview, если вы не хотите, чтобы ваш класс рендеринга «начинал» каждый раз, когда вы возвращаетесь к своему фрагменту с помощью glsurfaceview. Вместо этого создайте свой класс рендеринга в своих фрагментах onCreate, таким образом, если у вас есть что-то настроенное, вы начнете прямо там, где вы ушли, поскольку просто настройка рендеринга предоставит вам поверхность, которая вызовет вызов onsurfacecreated, onsurfacechanged и ondrawframe автоматически. Убедитесь, что вы перезагрузите все ресурсы, которые вы в последний раз использовали в onsurfacecreated, в ondrawframe перед их рисованием.

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

Когда дело доходит до приостановки и возобновления фрагмента, то в большинстве случаев это автоматически обрабатывается, когда вы динамически заменяете фрагмент и добавляете его в стопку, поэтому просто добавляйте surface.onpause () и surface.onResume () в правильные места И вам хорошо идти.

Чтобы сделать вещи кристально чистыми, попробуйте помещать записи журнала в методы, вращающиеся вокруг жизненного цикла фрагмента и средства визуализации glsurfaceview, и вы сможете увидеть, что происходит и чего не происходит.

Я не работаю с фрагментами, но если glsurface был уничтожен, возможно, придется снова создать экземпляр OpenGLRenderer и реанимировать его на glururface, этот код работает для меня в действиях при изменении ориентации и воссоздании всего экрана, в этом случае я должен Снова настройте контентное представление макета для сброса glsurfaceview:

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

Если вы не перезапустите и не настроите весь контент, попробуйте создать новый объект GLSurface:

 this.view = new GLSurfaceView(); 

Я не эксперт в OpenGL ES , но я достаточно много пробивался по фрагментам и их жизненному циклу. Я предлагаю вам установить onCreateView для вашего фрагмента, попросить рендеринга снова начать рисовать, и если это не сработает, попробуйте сделать это из onResume из фрагмента. Не нужно ничего делать с уровня активности, когда дело касается рисования поверхности GL в фрагменте.

Intereting Posts
SMS Broadcastreceiver не вызывается, когда установлен GO SMS Pro Понимание концепций Android с точки зрения развития рабочего стола Ресурс не найден, идентификатор отсутствующего элемента отсутствует Qt Тип платформы проверки: мобильный или рабочий стол Как удалить черную границу из AlertDialog builder Запись файла на SDCard в Android Android File Transfer не может видеть папку, созданную приложением Как загружать только новые элементы в pull для обновления пользовательского списка? Проигрыватель ListView для Android RemoteViews Сохранение нижнего элемента списка ListView при появлении клавиатуры Android: Как вы смешиваете макет ViewPager с макетом не-ViewPager для разных ориентаций устройств? Создайте новый Android-проект на базе Gradle в IntelliJ IDEA Как установить размер изображения? Могу ли я использовать Javascript для получения заголовка компаса для iOS и Android? Продолжить службу, даже если приложение очищено от последнего приложения