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