Ios JavaFXPorts-移动设备上的滚动条问题

Ios JavaFXPorts-移动设备上的滚动条问题,ios,scrollbar,gluon,javafxports,gluon-mobile,Ios,Scrollbar,Gluon,Javafxports,Gluon Mobile,我目前正在用JavaFX开发一个移动应用程序,使用GluonHQ和JavaFXPorts。我的一个屏幕包含一个listview,你可以从下面的截图中看到,截图取自我的iPhone 6 我注意到移动设备中的滚动条存在以下问题: 我第一次触摸屏幕时,滚动条显示有点不对位,然后移动到正确的位置。这只是第一次很快发生。(截图) 我注意到滚动条在每次触摸屏幕时都会出现,而不仅仅是在触摸和拖动屏幕时。在本机iOS应用程序上,滚动条仅在触摸和拖动时显示。如果将手指放在屏幕上,然后将其移除,则不会显示滚动条 当

我目前正在用JavaFX开发一个移动应用程序,使用GluonHQ和JavaFXPorts。我的一个屏幕包含一个listview,你可以从下面的截图中看到,截图取自我的iPhone 6

我注意到移动设备中的滚动条存在以下问题:

  • 我第一次触摸屏幕时,滚动条显示有点不对位,然后移动到正确的位置。这只是第一次很快发生。(截图)
  • 我注意到滚动条在每次触摸屏幕时都会出现,而不仅仅是在触摸和拖动屏幕时。在本机iOS应用程序上,滚动条仅在触摸和拖动时显示。如果将手指放在屏幕上,然后将其移除,则不会显示滚动条
  • 当我将手指从屏幕上移开时,滚动条总是需要一些时间才能消失,而在本机应用程序中,滚动条会立即消失
  • 有人能帮我解决这些问题吗。如何定义滚动条在再次隐藏之前出现的时间

    您可以通过创建一个ListView并加载一些项目来体验这种情况

    更新

    多亏了下面Jose Pereda的回答,我成功地克服了上述三个问题。下面是我用来达到预期结果的代码。快速了解新滚动条的显示和行为。何塞,你是老板!请继续提出改进意见

    public class ScrollBarView {
    
       public static void changeView(ListView<?> listView) {
    
           listView.skinProperty().addListener(new ChangeListener<Object>() {
               private StackPane thumb;
               private ScrollBar scrollBar;
               boolean touchReleased = true, inertia = false;
    
               @Override
               public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
                   scrollBar = (ScrollBar) listView.lookup(".scroll-bar");
    
                   // "hide" thumb as soon as the scroll ends
                   listView.setOnScrollFinished(e -> {
                      if (thumb != null) {
                         touchReleased = true;
                         playAnimation();
                      } // if
                   });
    
                   // Fix for 1. When user touches first time, the bar is set invisible so that user cannot see it is
                   // placed in the wrong position.
                   listView.setOnTouchPressed(e -> {
                      if (thumb == null) {
                         thumb = (StackPane) scrollBar.lookup(".thumb");
                         thumb.setOpacity(0);
                         initHideBarAnimation();
                      } // if
                   });
    
                   // Try to play animation whenever an inertia scroll takes place
                   listView.addEventFilter(ScrollEvent.SCROLL, e -> {
                       inertia = e.isInertia();
                       playAnimation();
                   });
    
                   // As soon as the scrolling starts the thumb become visible.
                   listView.setOnScrollStarted(e -> {
                       sbTouchTimeline.stop();
                       thumb.setOpacity(1);
                       touchReleased = false;
                   });
               } // changed
    
               private Timeline sbTouchTimeline;
               private KeyFrame sbTouchKF1, sbTouchKF2;
    
               // Initialize the animation that hides the thumb when no scrolling takes place.
               private void initHideBarAnimation() {
                  if (sbTouchTimeline == null) {
                     sbTouchTimeline = new Timeline();
                     sbTouchKF1 = new KeyFrame(Duration.millis(50), new KeyValue(thumb.opacityProperty(), 1));
                     sbTouchKF2 = new KeyFrame(Duration.millis(200), (e) -> inertia = false, new KeyValue(thumb.opacityProperty(), 0));
                     sbTouchTimeline.getKeyFrames().addAll(sbTouchKF1, sbTouchKF2);
                  } // if
               } // initHideBarAnimation
    
               // Play animation whenever touch is released, and when an inertia scroll is running but thumb reached its bounds.
               private void playAnimation() {
                  if(touchReleased)
                     if(!inertia || (scrollBar.getValue() != 0.0 && scrollBar.getValue() != 1))
                        sbTouchTimeline.playFromStart();
               } // playAnimation()
           });
       } // changeView
    } // ScrollBarView
    
    公共类滚动条视图{
    公共静态无效变更视图(ListView ListView){
    listView.skinProperty().addListener(新的ChangeListener()){
    私人拇指;
    私有滚动条滚动条;
    布尔值=真,惯性=假;
    @凌驾
    
    public void已更改(ObservalEvalue如评论中所述,第一个问题已知,目前尚未解决。问题似乎与滚动条的初始宽度有关(桌面为20像素),然后设置为8像素(触摸设备为8像素),并移动到其最终位置,向右移动12个像素

    至于第二个和第三个问题,如果您不想自己修补和构建JDK,可以覆盖默认行为,因为
    滚动条
    控件是ListView的
    VirtualFlow
    控件的一部分,可以在运行时通过查找找到这两个控件

    拥有控件后,您可以根据需要使用其可见性。此属性的唯一问题是它已绑定,并且不断从
    layoutChildren
    方法调用

    这是一个相当粗糙的解决方案,但它适用于2)和3):

    公共类基本视图扩展视图{
    私有最终列表视图列表视图;
    私有滚动条滚动条;
    私人拇指;
    公共基本视图(字符串名称){
    超级(姓名);
    listView=新建listView();
    //添加您的项目
    final InvalizationListener skinListener=新的InvalizationListener(){
    @凌驾
    公共无效(可观察到){
    如果(listView.getSkin()!=null){
    listView.skinProperty().RemovelListener(此);
    scrollbar=(scrollbar)listView.lookup(“.scrollbar”);
    listView.setOnScrollFinished(e->{
    if(thumb!=null){
    //滚动/拖动结束后立即“隐藏”拇指
    thumb.setStyle(“-fx背景色:透明;”);
    }
    });
    setOnScrollStarted(e->{
    if(thumb==null){
    thumb=(StackPane)滚动条查找(“.thumb”);
    }
    if(thumb!=null){
    //仅当滚动/拖动开始时才再次“显示”拇指
    thumb.setStyle(“-fx背景色:#898989;”);
    }
    });
    }
    }
    };
    listView.skinProperty().addListener(skinListener);
    设置中心(列表视图);
    }
    }
    
    已知第一个问题。不确定是否可以隐藏(可见/不透明度)滚动条。第二个和第三个问题:这是JavaFX for touch enable设备定义滚动条行为的方式(参见第622行和第2904行)@JoséPereda有没有办法覆盖第622行和第2904行中定义的默认行为?是的,您可以覆盖它。我已经发布了一个答案。这不是一个确定的解决方案,但可能足以解决您的问题?我已经用视频和代码更新了我的帖子,展示了我是如何解决问题1的。@javasuns看起来非常顺利没有w、 干得好!
    public class BasicView extends View {
    
        private final ListView<String> listView;
        private ScrollBar scrollbar;
        private StackPane thumb;
    
        public BasicView(String name) {
            super(name);
    
            listView = new ListView<>();
            // add your items
    
            final InvalidationListener skinListener = new InvalidationListener() {
                @Override
                public void invalidated(Observable observable) {
                    if (listView.getSkin() != null) {
                        listView.skinProperty().removeListener(this);
                        scrollbar = (ScrollBar) listView.lookup(".scroll-bar");
                        listView.setOnScrollFinished(e -> {
                            if (thumb != null) {
                                // "hide" thumb as soon as scroll/drag ends
                                thumb.setStyle("-fx-background-color: transparent;");
                            }
                        });
                        listView.setOnScrollStarted(e -> {
                            if (thumb == null) {
                                thumb = (StackPane) scrollbar.lookup(".thumb");
                            }
                            if (thumb != null) {
                                // "show" thumb again only when scroll/drag starts
                                thumb.setStyle("-fx-background-color: #898989;");
                            }
                        });
    
                    }
                }
            };
            listView.skinProperty().addListener(skinListener);
            setCenter(listView);
        }
    
    }