mobileapplication.mobileevent BACK_BUTTON_PRESSED

2020-05-05 00:58发布

问题:

I've got 2 android native audio instances in two of my views. I'm trying to get the audio to stop when the user presses the back button and leaves the view as it's not happening automatically. I've looked at the documentation and seen the MobileEvent class. I've tried implementing it's constructor with no luck. This is my first app altogether and I've only just learnt Java and JavaFX on my own for this purpose so some help would be great. My current attempt is below.

    public void MobileEvent(javafx.event.EventTarget source,
               javafx.event.EventType<MobileApplication.MobileEvent> BACK_BUTTON_PRESSED) {
    service.backPressed();
}

This is a Gluon application.

回答1:

The idea of a custom event like MobileEvent.BACK_BUTTON_PRESSED is that you can subscribe to it using an event handler.

For instance, if you create a layer and you want to close it when the user presses the back button:

public BasicView(String name) {
    super(name);

    // create a custom layer
    MobileApplication.getInstance().addLayerFactory("My Layer", () -> new Layer() {
        private final Node root;
        private final double size = 300;

        {
            root = new StackPane(new Button("A custom layer"));
            root.setStyle("-fx-background-color: lightgreen;");
            getChildren().add(root);
            getApp().getGlassPane().getLayers().add(this);

            // Add event handler to listen to Android Back Button Pressed event, hiding the layer
            addEventHandler(MobileApplication.MobileEvent.BACK_BUTTON_PRESSED, e -> {
                    hide();
                    e.consume();
            });
        }

        @Override
        public void hide() {
            setShowing(false);
            super.hide(); 
        }

        @Override
        public void layoutChildren() {
            root.setVisible(isShowing());
            if (!isShowing()) {
                return;
            }
            root.resize(size, size);
            resizeRelocate(0, 0, size, size);
        }
    });

    Button button = new Button("Show Layer");
    button.setOnAction(e -> MobileApplication.getInstance().showLayer("My Layer"));

    VBox controls = new VBox(15.0, button);
    controls.setAlignment(Pos.CENTER);

    setCenter(controls);
}

If you create a Single View project, use the snippet above, and deploy it on an Android device, you can verify that when you click the button the layer shows up, and if you hit the Android back button, it will close the layer.

Notice that if you hit it again, it will close the app: The home view already has a listener on this event, that's why the app gets closed. Or if you are in a secondary view, with this event you will return to the previous view.

While you can subscribe to this event at any point in your code, like I've done in the example above, there are already other events that you can track more easily. For instance, the LifecycleEvent events, likeSHOWINGorHIDING`, are already used by all the Views.

So you can add to your custom view a listener to any of those events:

public BasicView(String name) {
    super(name);

    Label label = new Label("This is a custom view");

    VBox controls = new VBox(15.0, label);
    controls.setAlignment(Pos.CENTER);

    setCenter(controls);

    setOnShowing(e -> System.out.println("Showing Event"));

    setOnHiding(e -> System.out.println("Hiding Event"));
}

Note that in your case, you can easily find out when the user leaves the view, and then react accordingly calling the service to stop the audio:

    setOnHiding(e -> {
        Services.get(MyAudioService.class).ifPresent(service -> service.stop());
    });