JavaFXPorts: Selected item in ListView is not sele

2019-01-28 21:12发布

问题:

Here is sample code:

package com.javafxportslistviewdemo;

import com.gluonhq.charm.down.Platform;
import com.gluonhq.charm.down.Services;
import com.gluonhq.charm.down.plugins.LifecycleEvent;
import com.gluonhq.charm.down.plugins.LifecycleService;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;

import javafx.stage.Stage;

public class JavaFXPortsListViewDemo extends Application {

    @Override
    public void init() {
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Screen primaryScreen = Screen.getPrimary();
        Rectangle2D visualBounds = primaryScreen.getVisualBounds();
        double width = visualBounds.getWidth();
        double height = visualBounds.getHeight();

        Label label = new Label("Here is selected item...");

        ListView<String> listView = new ListView<>();
        ObservableList<String> items = FXCollections.observableArrayList(
                "one", "two", "three", "four");
        listView.setItems(items);
        listView.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends String> ov, String old_val, String new_val) -> {
            label.setText(new_val);
        });

        VBox root = new VBox();
        root.getChildren().addAll(label, listView);

        Scene scene = new Scene(root, width, height);

        Services.get(LifecycleService.class).ifPresent(ls -> {
            ls.addListener(LifecycleEvent.PAUSE, () -> onPause());
            ls.addListener(LifecycleEvent.RESUME, () -> onResume());
        });

        scene.addEventHandler(KeyEvent.KEY_RELEASED, e -> {
            if (KeyCode.ESCAPE.equals(e.getCode())) {
                if (Platform.isAndroid()) {
                    // bring up the menu or other Android stuff
                    Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
                } else {
                    // bring up the menu or other Desktop stuff
                    Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
                }
            }
        });

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void onPause() {
    }

    private void onResume() {
    }
}

Environment for development: JavaFXPorts 8.60.8, javafxmobile-plugin 1.1.0, Gluon Plugin 2.4.0, NetBeans 8.1, Windows 10 Pro, 64-bit

Environment for testing: Android device Samsung Galaxy A5 2016, Android 6.0.1

Steps to reproduce: 1. Build sample code with: JavaFXPorts 8.60.8, javafxmobile-plugin 1.1.0, Gluon Plugin 2.4.0; 2. Install and Run sample on Android device (Android 6.0.1); 3. Touch on ListView and Select any item from ListView - item is not selected -> BUG

Added bug for issue tracker of JavaFXPorts: JavaFXPorts issue

回答1:

Thanks for reporting the issue.

It is already known that in some Samsung devices the touch event handling doesn't work as in the rest of Android devices.

While this is fixed in JavaFXPorts, you can use the following workaround: provide a listener to the ListCell that wires internally the selection.

Based on your sample:

    ListView<String> listView = new ListView<>();
    listView.setCellFactory(p -> new ListCell<String>() {

        private String item;
        {
            setOnMouseClicked(e -> listView.getSelectionModel().select(item));
        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty); 
            this.item = item;
            setText(item);
        }

    });
    listView.getSelectionModel().selectedItemProperty()
      .addListener((ov, old_val, new_val) -> label.setText(new_val));