带有GLSurfaceView的Android片段
我有一些当前在活动上运行的代码,我正在将其转换为使用一个主活动和几个片段来运行。我的一个活动在onCreate()方法中运行GLSurfaceView。因此,我将其修改为onCreateView。但问题是,每当新片段尝试启动时,应用程序就会崩溃,我得到以下错误:带有GLSurfaceView的Android片段,android,android-fragments,glsurfaceview,Android,Android Fragments,Glsurfaceview,我有一些当前在活动上运行的代码,我正在将其转换为使用一个主活动和几个片段来运行。我的一个活动在onCreate()方法中运行GLSurfaceView。因此,我将其修改为onCreateView。但问题是,每当新片段尝试启动时,应用程序就会崩溃,我得到以下错误: E/GLSurfaceView: eglCreateWindowSurface java.lang.IllegalArgumentException: Make sure the SurfaceView
E/GLSurfaceView: eglCreateWindowSurface
java.lang.IllegalArgumentException: Make sure the SurfaceView or associated SurfaceHolder has a valid Surface
at com.google.android.gles_jni.EGLImpl._eglCreateWindowSurface(Native Method)
at com.google.android.gles_jni.EGLImpl.eglCreateWindowSurface(EGLImpl.java:90)
at android.opengl.GLSurfaceView$DefaultWindowSurfaceFactory.createWindowSurface(GLSurfaceView.java:808)
at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:1077)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1471)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
有谁能给我一个提示,说明我在转换成碎片时做错了什么
下面是我在主要活动中启动第一个片段的地方:
//Start the fragment
Fragment gameManager = new GameManager();
fragmentManager.beginTransaction()
.add(R.id.fragment_container,gameManager)
.addToBackStack(null)
.commit();
以下是GameManager的相关代码,它是一个片段:
(1) 空构造函数:
public GameManager(){
}
(2) onCreateView()代码:
@覆盖
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
fa=(FragmentActivity)super.getActivity();
CatAndroidApp=(CatAndroidApp)getActivity().getApplicationContext();
RelativeLayout框架=新的RelativeLayout(getActivity());
TextureManager纹理=app.getTextureManagerInstance();
如果(纹理==null){
纹理=新的TextureManager(getResources());
app.settexturemanager实例(纹理);
}
//更改的构造函数
视图=新游戏视图(这个,getActivity());
渲染器=新游戏渲染器(视图);
view.setRenderer(渲染器);
view.requestFocus();
view.setLayoutParams(新的LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_父级,
LinearLayout.LayoutParams.MATCH_PARENT,1));
frame.addView(视图);
布尔水平=getActivity().getResources().getDisplayMetrics().widthPixels
最后,这里是GameView的代码:
package com.catandroid.app.common.ui.views;
import javax.microedition.khronos.opengles.GL10;
import com.catandroid.app.common.components.BoardGeometry;
import com.catandroid.app.CatAndroidApp;
import com.catandroid.app.common.controllers.GameManager;
import com.catandroid.app.common.controllers.GameRenderer;
import com.catandroid.app.common.ui.TextureManager;
import com.catandroid.app.common.ui.resources.UIButton;
import com.catandroid.app.common.ui.resources.UIButton.Type;
import com.catandroid.app.common.players.Player;
import android.content.Context;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.os.Vibrator;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
public class GameView extends GLSurfaceView implements OnGestureListener,
OnDoubleTapListener, OnScaleGestureListener {
private int width, height;
private GameRenderer renderer;
private GestureDetector gesture;
private ScaleGestureDetector pinch;
private UIButton[] buttons;
private boolean buttonsPlaced = false;
private GameManager game;
public GameView(GameManager manager, Context context) {
super(context);
game = manager;
gesture = new GestureDetector(context, this);
pinch = new ScaleGestureDetector(context, this);
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
buttons = new UIButton[UIButton.Type.values().length];
int size = (int) (0.5 * BoardGeometry.BUTTON_SIZE * getResources().getDisplayMetrics().density);
for (UIButton.Type type : UIButton.Type.values())
buttons[type.ordinal()] = new UIButton(type, size, size);
buttonsPlaced = false;
}
@Override
public void setRenderer(Renderer renderer) {
super.setRenderer(renderer);
this.renderer = (GameRenderer) renderer;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
renderer.setSize(getContext().getResources().getDisplayMetrics(), width, height);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// handle touch events in GestureDetector
return gesture.onTouchEvent(event) || pinch.onTouchEvent(event);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distX, float distY) {
// ignore scrolling started over a button
for (UIButton button : buttons)
if (button.isPressed())
return false;
// shift the board
renderer.getGeometry().translate(distX, distY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vx, float vy) {
// throw out button press if scrolling over a button
release((int) e2.getX(), (int) e2.getY(), false);
// ignore flings
return false;
}
@Override
public boolean onDown(MotionEvent event) {
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
// press down (consider activating buttons)
press((int) event.getX(), (int) event.getY());
// always return true to allow gestures to register
return true;
}
@Override
public void onShowPress(MotionEvent event) {
// this is handled already in onDown
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
// handle in onSingleTapConfirmed
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// button click
return release((int) event.getX(), (int) event.getY(), true);
}
@Override
public void onLongPress(MotionEvent event) {
// TODO: long press resource to trade for it
Vibrator vibrator = (Vibrator) getContext().getSystemService(
Context.VIBRATOR_SERVICE);
// consider buttons then a click on the board
if (release((int) event.getX(), (int) event.getY(), true) ||
click((int) event.getX(), (int) event.getY())) {
vibrator.vibrate(50);
} else {
vibrator.vibrate(20);
}
}
@Override
public boolean onDoubleTapEvent(MotionEvent event) {
// ignore intermediate events triggered in a double tap
return false;
}
@Override
public boolean onDoubleTap(MotionEvent event) {
// try to ignore double taps on a button
if (release((int) event.getX(), (int) event.getY(), false))
return true;
// double top zooms to point or zooms out
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.toggleZoom((int) event.getX(), (int) event.getY());
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.zoomBy(detector.getScaleFactor());
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void addButton(Type type) {
buttons[type.ordinal()].setEnabled(true);
buttonsPlaced = false;
}
public void removeButtons() {
for (UIButton button : buttons)
button.setEnabled(false);
}
public void placeButtons(int width, int height) {
if (buttonsPlaced)
return;
// first button is always in the top left corner
int x = 0;
int y = height;
for (UIButton button : buttons) {
if (!button.isEnabled())
continue;
int endwidth = width - button.getWidth() / 2;
int endheight = button.getHeight() / 2;
// set position
UIButton.Type type = button.getType();
if (type == UIButton.Type.CANCEL || type == UIButton.Type.ROLL
|| type == UIButton.Type.ENDTURN) {
// set position to far right/bottom
if (width < height)
button.setPosition(endwidth,
height - button.getHeight() / 2);
else
button.setPosition(button.getWidth() / 2, endheight);
} else {
// set to next available position
button.setPosition(x + button.getWidth() / 2,
y - button.getHeight() / 2);
// get next position
if (height >= width) {
// portrait
int size = button.getWidth();
x += size;
if (x + 1.5 * size > endwidth) {
x = 0;
y -= button.getHeight();
}
} else {
// landscape
int size = button.getHeight();
y -= size;
if (y - 1.5 * size < endheight) {
y = height;
x += button.getWidth();
}
}
}
}
buttonsPlaced = true;
}
public void drawButtons(TextureManager texture, GL10 gl) {
for (UIButton button : buttons) {
if (button.isEnabled())
texture.draw(button, gl);
}
}
private boolean click(int x, int y) {
Player player = CatAndroidApp.getInstance().getBoardInstance().getCurrentPlayer();
BoardGeometry boardGeometry = renderer.getGeometry();
GameRenderer.Action action = renderer.getAction();
if (!player.isHuman())
return false;
int select = -1;
switch (action) {
case NONE:
return false;
case ROBBER:
// select a hexagon
select = boardGeometry.getNearestHexagon(x, y);
break;
case TOWN:
case CITY:
// select a vertex
select = boardGeometry.getNearestVertex(x, y);
break;
case ROAD:
// select an edge
select = boardGeometry.getNearestEdge(x, y);
break;
}
if (select >= 0) {
game.select(action, select);
return true;
}
return false;
}
private boolean press(int x, int y) {
// consider buttons
for (UIButton button : buttons) {
if (button != null && button.press(x, height - y))
return true;
}
return false;
}
private boolean release(int x, int y, boolean activate) {
boolean released = false;
// consider buttons
for (UIButton button : buttons) {
if (button.release(x, height - y)) {
released = true;
if (activate)
game.buttonPress(button.getType());
}
}
return released;
}
}
package com.carandroid.app.common.ui.views;
导入javax.microedition.khronos.opengles.GL10;
导入com.carandroid.app.common.components.BoardGeometry;
导入com.carandroid.app.carandroidapp;
导入com.carandroid.app.common.controllers.GameManager;
导入com.carandroid.app.common.controllers.GameRenderer;
导入com.carandroid.app.common.ui.TextureManager;
导入com.carandroid.app.common.ui.resources.ui按钮;
导入com.carandroid.app.common.ui.resources.UIButton.Type;
导入com.carandroid.app.common.players.Player;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.opengl.GLSurfaceView;
导入android.os.可控震源;
导入android.view.MotionEvent;
导入android.view.GestureDetector;
导入android.view.scalegestruedetector;
导入android.view.scalegestruedetector.OnScaleGestureListener;
导入android.view.view;
导入android.view.GestureDetector.OnDoubleTapListener;
导入android.view.GestureDetector.OnTestureListener;
公共类GameView扩展了GLSurfaceView在EstureListener上的实现,
OnDoubleTapListener,OnScale Listener{
私人int宽度、高度;
私人游戏机;
私人手势;
私用鳞片测试器夹;
专用UIButton[]按钮;
private boolean buttonsPlaced=false;
私人游戏经理游戏;
公共游戏视图(游戏管理器,上下文){
超级(上下文);
游戏=经理;
手势=新的手势检测器(上下文,此);
pinch=新的scalegestruedetector(上下文,this);
设置系统兼容性(getSystemUiVisibility()| View.SYSTEM_UI_FLAG_LOW_PROFILE);
buttons=newUIButton[UIButton.Type.values().length];
int size=(int)(0.5*BoardGeometry.BUTTON_size*getResources().getDisplayMetrics().density);
对于(UIButton.Type类型:UIButton.Type.values())
按钮[type.ordinal()]=新的UIButton(类型、大小、大小);
按钮位置=假;
}
@凌驾
公共void集渲染器(渲染器){
setRenderer(渲染器);
this.renderer=(游戏渲染器)渲染器;
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
宽度=MeasureSpec.getSize(widthMeasureSpec);
高度=测量等级getSize(高度测量等级);
设置测量尺寸(宽度、高度);
renderer.setSize(getContext().getResources().getDisplayMetrics(),宽度,高度);
}
@凌驾
公共布尔onTouchEvent(运动事件){
//在手势检测器中处理触摸事件
返回手势.onTouchEvent(事件)| | pinch.onTouchEvent(事件);
}
@凌驾
公共布尔onScroll(MotionEvent e1、MotionEvent e2、float distX、float distY){
//忽略在按钮上启动的滚动
用于(UIButton:按钮)
if(button.isPressed())
返回false;
//转移董事会
renderer.getGeometry().translate(distX,distY);
返回true;
}
@凌驾
公共布尔onFling(运动事件e1、运动事件e2、浮点vx、浮点vy){
//如果滚动到按钮上,则抛出按钮按下
release((int)e2.getX(),(int)e2.getY(),false);
//不理睬放纵
返回false;
}
@凌驾
公共布尔onDown(运动事件){
设置系统兼容性(getSystemUiVisibility()|视图。
package com.catandroid.app.common.ui.views;
import javax.microedition.khronos.opengles.GL10;
import com.catandroid.app.common.components.BoardGeometry;
import com.catandroid.app.CatAndroidApp;
import com.catandroid.app.common.controllers.GameManager;
import com.catandroid.app.common.controllers.GameRenderer;
import com.catandroid.app.common.ui.TextureManager;
import com.catandroid.app.common.ui.resources.UIButton;
import com.catandroid.app.common.ui.resources.UIButton.Type;
import com.catandroid.app.common.players.Player;
import android.content.Context;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.os.Vibrator;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
public class GameView extends GLSurfaceView implements OnGestureListener,
OnDoubleTapListener, OnScaleGestureListener {
private int width, height;
private GameRenderer renderer;
private GestureDetector gesture;
private ScaleGestureDetector pinch;
private UIButton[] buttons;
private boolean buttonsPlaced = false;
private GameManager game;
public GameView(GameManager manager, Context context) {
super(context);
game = manager;
gesture = new GestureDetector(context, this);
pinch = new ScaleGestureDetector(context, this);
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
buttons = new UIButton[UIButton.Type.values().length];
int size = (int) (0.5 * BoardGeometry.BUTTON_SIZE * getResources().getDisplayMetrics().density);
for (UIButton.Type type : UIButton.Type.values())
buttons[type.ordinal()] = new UIButton(type, size, size);
buttonsPlaced = false;
}
@Override
public void setRenderer(Renderer renderer) {
super.setRenderer(renderer);
this.renderer = (GameRenderer) renderer;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
renderer.setSize(getContext().getResources().getDisplayMetrics(), width, height);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// handle touch events in GestureDetector
return gesture.onTouchEvent(event) || pinch.onTouchEvent(event);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distX, float distY) {
// ignore scrolling started over a button
for (UIButton button : buttons)
if (button.isPressed())
return false;
// shift the board
renderer.getGeometry().translate(distX, distY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vx, float vy) {
// throw out button press if scrolling over a button
release((int) e2.getX(), (int) e2.getY(), false);
// ignore flings
return false;
}
@Override
public boolean onDown(MotionEvent event) {
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
// press down (consider activating buttons)
press((int) event.getX(), (int) event.getY());
// always return true to allow gestures to register
return true;
}
@Override
public void onShowPress(MotionEvent event) {
// this is handled already in onDown
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
// handle in onSingleTapConfirmed
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// button click
return release((int) event.getX(), (int) event.getY(), true);
}
@Override
public void onLongPress(MotionEvent event) {
// TODO: long press resource to trade for it
Vibrator vibrator = (Vibrator) getContext().getSystemService(
Context.VIBRATOR_SERVICE);
// consider buttons then a click on the board
if (release((int) event.getX(), (int) event.getY(), true) ||
click((int) event.getX(), (int) event.getY())) {
vibrator.vibrate(50);
} else {
vibrator.vibrate(20);
}
}
@Override
public boolean onDoubleTapEvent(MotionEvent event) {
// ignore intermediate events triggered in a double tap
return false;
}
@Override
public boolean onDoubleTap(MotionEvent event) {
// try to ignore double taps on a button
if (release((int) event.getX(), (int) event.getY(), false))
return true;
// double top zooms to point or zooms out
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.toggleZoom((int) event.getX(), (int) event.getY());
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.zoomBy(detector.getScaleFactor());
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void addButton(Type type) {
buttons[type.ordinal()].setEnabled(true);
buttonsPlaced = false;
}
public void removeButtons() {
for (UIButton button : buttons)
button.setEnabled(false);
}
public void placeButtons(int width, int height) {
if (buttonsPlaced)
return;
// first button is always in the top left corner
int x = 0;
int y = height;
for (UIButton button : buttons) {
if (!button.isEnabled())
continue;
int endwidth = width - button.getWidth() / 2;
int endheight = button.getHeight() / 2;
// set position
UIButton.Type type = button.getType();
if (type == UIButton.Type.CANCEL || type == UIButton.Type.ROLL
|| type == UIButton.Type.ENDTURN) {
// set position to far right/bottom
if (width < height)
button.setPosition(endwidth,
height - button.getHeight() / 2);
else
button.setPosition(button.getWidth() / 2, endheight);
} else {
// set to next available position
button.setPosition(x + button.getWidth() / 2,
y - button.getHeight() / 2);
// get next position
if (height >= width) {
// portrait
int size = button.getWidth();
x += size;
if (x + 1.5 * size > endwidth) {
x = 0;
y -= button.getHeight();
}
} else {
// landscape
int size = button.getHeight();
y -= size;
if (y - 1.5 * size < endheight) {
y = height;
x += button.getWidth();
}
}
}
}
buttonsPlaced = true;
}
public void drawButtons(TextureManager texture, GL10 gl) {
for (UIButton button : buttons) {
if (button.isEnabled())
texture.draw(button, gl);
}
}
private boolean click(int x, int y) {
Player player = CatAndroidApp.getInstance().getBoardInstance().getCurrentPlayer();
BoardGeometry boardGeometry = renderer.getGeometry();
GameRenderer.Action action = renderer.getAction();
if (!player.isHuman())
return false;
int select = -1;
switch (action) {
case NONE:
return false;
case ROBBER:
// select a hexagon
select = boardGeometry.getNearestHexagon(x, y);
break;
case TOWN:
case CITY:
// select a vertex
select = boardGeometry.getNearestVertex(x, y);
break;
case ROAD:
// select an edge
select = boardGeometry.getNearestEdge(x, y);
break;
}
if (select >= 0) {
game.select(action, select);
return true;
}
return false;
}
private boolean press(int x, int y) {
// consider buttons
for (UIButton button : buttons) {
if (button != null && button.press(x, height - y))
return true;
}
return false;
}
private boolean release(int x, int y, boolean activate) {
boolean released = false;
// consider buttons
for (UIButton button : buttons) {
if (button.release(x, height - y)) {
released = true;
if (activate)
game.buttonPress(button.getType());
}
}
return released;
}
}