В моем Android-приложении есть панель вкладок, в которой для запуска контента на каждой вкладке используется Намерение, как в демонстрациях API Android , пример . Я поместил действие AndEngine под одну из вкладок. Мой первый вопрос: это разумная идея? Или, если я использую AndEngine, лучше ли реализовать весь пользовательский интерфейс моего приложения в AndEngine?
Предполагая, что я еще не начинаю, конкретная проблема, с которой я столкнулся, заключается в следующем. Это действие AndEngine, которое я включил в свое приложение на основе вкладок, представляет собой упрощенную версию AndEngine PinchZoom пример . Это работает хорошо, пока вы не переключитесь с вкладки, а затем снова вернетесь. В этот момент вид снова появляется, но вы больше не можете прокручивать или масштабировать.
Вот мой класс деятельности. Дайте мне знать, если вы хотите увидеть класс панели вкладок тоже. Как вы можете видеть, я пытался отключить различные прослушиватели и детекторы, когда пользователь покидает вкладку, и включить их снова, когда они вернутся. Но я установил, используя точку останова, что onSceneTouchEvent
не вызывается, когда я касаюсь экрана после возврата на вкладку. Что-то вмешивается и захватывает мои сенсорные события? Или есть что-то, что становится неактивным и нуждается в возвращении к жизни?
Я также разместил этот вопрос на форумах AndEngine.
Edit:
Спасибо за ваши предложения, Гийом. Вы правы, что 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);
}
}