其他分享
首页 > 其他分享> > 为什么我的标签栏会中断我的AndEngine活动?

为什么我的标签栏会中断我的AndEngine活动?

作者:互联网

我的Android应用程序具有一个标签栏,该标签栏使用Intent来启动每个标签中的内容,就像Android的API Demos example一样.我的第一个问题是:这是一个合理的主意吗?或者,如果我使用的是AndEngine,那么在AndEngine中实现应用的整个UI是否更好?

假设我还没有入门,那么我遇到的具体问题如下.这个AndEngine活动(我已将其集成到基于选项卡的应用程序中)是AndEngine PinchZoom example的简化版本.它运作良好,直到您离开选项卡然后再次返回.此时,该视图会重新出现,但是您无法再滚动或缩放.

这是我的活动课.让我知道您是否也想查看选项卡栏类.如您所见,我试图在用户离开选项卡时关闭各种侦听器和检测器,并在它们返回时将其重新打开.但是我已经建立了一个断点,当我返回到选项卡后触摸屏幕时,不会调用onSceneTouchEvent.是否有事情介入并捕获我的触摸事件?还是有一些东西变得不活跃,需要恢复生命?

我在AndEngine论坛上也有posted这个问题.

编辑:

谢谢你的建议,纪尧姆.没错,当用户返回到选项卡时,不会调用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);
    }
}

解决方法:

汤米:
我在自己的应用程序中也有同样的情况,其中我需要三个选项卡,其中一个是andEngine.但是我发现TabActivity并没有像触发新Intent一样重新初始化选项卡.如果您记录其他选项卡之一的生命周期,您将发现这不仅是andengine事物,而且是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的核心类,就找不到找到制表活动的方法,这超出了我在项目中的能力范围.

因此,我作为解决方法是这样做的:
我将这些选项卡构建为三个活动,它们共享一个页脚,使您可以在它们之间进行交换.我不得不仔细研究一下历史记录,并在适当的时候覆盖后退按钮的行为以保留在选项卡中.
另外,我在Android清单中使用了Intent标志:

android:launchMode="singleInstance"

确保仅创建了一个Andengine标签的实例,从而帮助该应用平稳运行.

希望这可以帮助.如果可以使andengine与TabActivity兼容,那就太好了,但是我认为目前还不完全.

标签:andengine,android
来源: https://codeday.me/bug/20191101/1985593.html