我的Android应用程序有一个标签栏,使用Intent在每个标签中启动内容,就像在Android的API Demos example中一样。我在其中一个标签下放了一个AndEngine活动。我的第一个问题是:这是一个合理的想法吗?或者,如果我使用AndEngine,在AndEngine中实现我的应用程序的整个UI是否更好?
假设我还没有进入非首发,我遇到的具体问题如下。这个AndEngine活动 - 我在基于选项卡的应用程序中加入的活动 - 是AndEngine PinchZoom example的简化版本。它可以很好地工作,直到您从标签切换然后再返回。此时,视图重新出现,但您无法再滚动或缩放。
这是我的活动课程。如果您想查看标签栏类,请告诉我。正如您所看到的,当用户离开选项卡时,我尝试关闭各种侦听器和检测器,并在返回时将其重新打开。但是我已经使用断点确定了在返回选项卡后触摸屏幕时未调用onSceneTouchEvent
。有什么干预和捕捉我的触摸事件?或者是否存在一些不活跃的东西需要恢复生机?
我在AndEngine论坛上也提到了posted这个问题。
修改
感谢您的建议,Guillaume。你是对的,当用户返回标签时不会调用onResumeGame
。我以为我已经检查过了,但是我必须把可滚动的图形同时放在两个标签下来让自己感到困惑。此时会调用onResume
方法,而onCreateGame
则不会。因此,我更改了代码,以便在onResume
中打开触摸检测器。这个方法肯定是在我希望的时候调用的,所以我猜这是进步,但是当我在返回选项卡后触摸屏幕时仍然没有触发onSceneTouchEvent
。更新后的代码如下,更改标记为// NEW
。
public class HomeActivity extends SimpleBaseGameActivity implements IOnSceneTouchListener,
IScrollDetectorListener, IPinchZoomDetectorListener {
private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 628;
private boolean mInitialised = false; // NEW
private Scene mScene;
private ZoomCamera mZoomCamera;
private ITexture mTexture;
private ITextureRegion mGrassTextureRegion;
private SurfaceScrollDetector mScrollDetector;
private PinchZoomDetector mPinchZoomDetector;
private float mPinchZoomStartedCameraZoomFactor;
@Override
public EngineOptions onCreateEngineOptions() {
this.mZoomCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
final EngineOptions engineOptions = new EngineOptions(true,
ScreenOrientation.PORTRAIT_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mZoomCamera);
if (MultiTouch.isSupported(this)) {
if (MultiTouch.isSupportedDistinct(this)) {
Toast.makeText(this, "MultiTouch detected.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(
this,
"MultiTouch detected, but your device has problems distinguishing between "
+ "fingers.", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "Sorry your device does NOT support MultiTouch!",
Toast.LENGTH_LONG).show();
}
return engineOptions;
}
@Override
public void onCreateResources() {
try {
this.mTexture = new BitmapTexture() {
@Override
protected InputStream onGetInputStream() throws IOException {
return getAssets().open("gfx/background_grass.png");
}
}.load(this.getTextureManager());
this.mGrassTextureRegion = TextureRegionFactory.extractFromTexture(mTexture);
} catch (IOException e) {
Debug.e(e);
}
}
@Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
this.mScene = new Scene();
this.mScene.setOnAreaTouchTraversalFrontToBack();
this.mScene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
// Calculate the coordinates for the sprite, so it's centered on the
// camera.
final float centerX = (CAMERA_WIDTH - this.mGrassTextureRegion.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mGrassTextureRegion.getHeight()) / 2;
// Create the sprite and add it to the scene.
final Sprite grass = new Sprite(centerX, centerY, this.mGrassTextureRegion,
this.getVertexBufferObjectManager());
this.mScene.attachChild(grass);
enableTouchDetectors(); // NEW
mInitialised = true; // NEW
return this.mScene;
}
@Override
public void onPause() {
this.mScene.setTouchAreaBindingOnActionDownEnabled(false);
this.mScene.setOnSceneTouchListener(null);
this.mPinchZoomDetector = null;
this.mScrollDetector = null;
super.onPause();
}
// NEW method
@Override
public void onResume() {
super.onResume();
// If returning to the tab, switch the touch detectors back on.
if (mInitialised) {
enableTouchDetectors();
}
}
// This method has been removed since Guillaume's answer.
// @Override
// public void onResumeGame() {
// super.onResumeGame();
// this.mScrollDetector = new SurfaceScrollDetector(this);
// this.mPinchZoomDetector = new PinchZoomDetector(this);
// this.mScene.setOnSceneTouchListener(this);
// this.mScene.setTouchAreaBindingOnActionDownEnabled(true);
// }
@Override
public void onScrollStarted(final ScrollDetector pScollDetector, final int pPointerID,
final float pDistanceX, final float pDistanceY) {
}
@Override
public void onScroll(final ScrollDetector pScollDetector, final int pPointerID,
final float pDistanceX, final float pDistanceY) {
final float zoomFactor = this.mZoomCamera.getZoomFactor();
this.mZoomCamera.offsetCenter(-pDistanceX / zoomFactor, -pDistanceY / zoomFactor);
}
@Override
public void onScrollFinished(final ScrollDetector pScollDetector, final int pPointerID,
final float pDistanceX, final float pDistanceY) {
}
@Override
public void onPinchZoomStarted(final PinchZoomDetector pPinchZoomDetector,
final TouchEvent pTouchEvent) {
this.mPinchZoomStartedCameraZoomFactor = this.mZoomCamera.getZoomFactor();
}
@Override
public void onPinchZoom(final PinchZoomDetector pPinchZoomDetector,
final TouchEvent pTouchEvent, final float pZoomFactor) {
this.mZoomCamera.setZoomFactor(this.mPinchZoomStartedCameraZoomFactor * pZoomFactor);
}
@Override
public void onPinchZoomFinished(final PinchZoomDetector pPinchZoomDetector,
final TouchEvent pTouchEvent, final float pZoomFactor) {
}
@Override
public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
this.mPinchZoomDetector.onTouchEvent(pSceneTouchEvent);
if (this.mPinchZoomDetector.isZooming()) {
this.mScrollDetector.setEnabled(false);
} else {
if (pSceneTouchEvent.isActionDown()) {
this.mScrollDetector.setEnabled(true);
}
this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
}
return true;
}
// NEW method
private void enableTouchDetectors() {
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mPinchZoomDetector = new PinchZoomDetector(this);
this.mScene.setOnSceneTouchListener(this);
this.mScene.setTouchAreaBindingOnActionDownEnabled(true);
}
}
答案 0 :(得分:2)
使用断点进行调试时,您的onResumeGame
方法是否被调用?
也许您需要在基本setOnSceneTouchListener(this)
中设置初始化(特别是onResume
)?或者您也可以尝试在onCreateScene
中添加它。
答案 1 :(得分:2)
托米: 我在自己的应用程序中有相同的场景,我需要三个选项卡,其中一个是andEngine。但是我发现TabActivity没有以与触发新Intent相同的方式重新初始化选项卡。如果你记录其他一个标签的生命周期,你会发现这不仅仅是一个动态的东西,而是一个TabActivity的东西。 关于这个问题,这里有一个非常有用的主题: http://groups.google.com/group/android-developers/browse_thread/thread/d89f1d5f913bb6f7
包括将每个标签设置为单个活动中的视图的示例。链接在这里。我使用了commonsware myeslf中的代码,发现他们的库和示例经过了充分的测试和高质量的测试。 https://github.com/commonsguy/cw-android/tree/master/Fancy/Tab/
无论如何,在没有重新编写Andengine核心类的情况下,我找不到一种方法来制作一个tabactivity工作,这超出了我在项目中可以做的范围。
所以我做的解决方法就是: 我自己构建标签作为三个共享页脚的活动,让您在它们之间进行交换。我不得不在历史记录中徘徊,并在适当的时候覆盖后退按钮的行为以保持在标签内。 另外,我在Android清单中使用了一个意图标志:
android:launchMode="singleInstance"
通过确保只创建了一个Andengine选项卡实例,帮助应用程序顺利运行。
希望这会有所帮助。如果andengine可以与TabActivity兼容,那将会很棒,但我认为此时并不完全。