2017-06-27 10 views
0

ViewにはListViewが含まれています。 初めてビューをロードすると、ListCellを作成するまでに時間がかかります。 UIがブロックされないように、listView.setItemsへの呼び出しをPlatform.runLaterにラップし、読み込みプロセスのインジケータとしてplaceHolderをlistViewに設定しました。
ビューAppBarには、TextFieldと一部のButtonsが含まれています。これらはCSSファイルでスタイルされています。ボタンのスタイルが正しく行われている間は、textFieldが最初に表示され、スタイルは適用されません。つまり、黒色になり、ListViewが読み込まれるとTextFieldのスタイルも適用されます。CSSスタイルがAppBarに適用されていません

この遅延の原因は何ですか?

@Override 
    protected void onShowing() { 
     appBar.setNavIcon(getBackButton()); 
     appBar.setTitle(searchField.getTextField()); 
     appBar.getActionItems().addAll(btnSort, btnFilter, moreMenu); 
    } 

    @Override 
    protected void onShown() { 
     setItems(); 
    } 

    protected void setItems() { 
     if (!firstShow) { 
      lview.setItems(items); 

     } else { 
      if (!items.isEmpty()) { 
       lview.setPlaceholder(new Label("loading data...")); 
       Platform.runLater(() -> lview.setItems(items)); 
      } 
      firstShow = false; 
     } 
    } 

EDIT:

これは、遅延の後に適用されるだけ-fx-テキストフィルです。その他のスタイルはすべてすぐに適用されます。

.app-bar > .title-box > .text-field{ 
    -fx-border-width: 0.0; 
    -fx-border-insets: 0.0; 
    -fx-padding: 0.0; 
    -fx-font-family: 'Roboto Medium'; 
    -fx-font-size: 20.0; 
    -fx-text-fill: -app-bar-item-color; 
    -fx-prompt-text-fill: #59819C; 
} 

.app-bar > .action-items .button{ 
    -fx-text-fill: red; 
} 

問題を再現するコード:コード掲載して

public class AppBarTestApp extends MobileApplication { 

    private static final String ITEMS_VIEW = "items"; 

    @Override 
    public void init() throws Exception { 

     addViewFactory(HOME_VIEW,() -> 
      { 
       Button btnShowNextView = new Button("Show items view"); 
       btnShowNextView.setOnAction(e -> switchView(ITEMS_VIEW)); 

       return new View(HOME_VIEW, new StackPane(btnShowNextView)); 
      }); 

     addViewFactory(ITEMS_VIEW, this::loadItemsView); 
    } 

    @Override 
    public void postInit(Scene scene) { 
     scene.getStylesheets().add(getClass().getResource("/com/jns/appbartest/view/common.css").toExternalForm()); 
    } 

    private View loadItemsView() { 
     URL resource = ItemsPresenter.class.getResource("items.fxml"); 
     FXMLLoader fxmlLoader = new FXMLLoader(resource); 

     try { 
      fxmlLoader.load(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return fxmlLoader.getRoot(); 
    } 
} 



public class ItemsPresenter { 

    private static final MobileApplication app  = MobileApplication.getInstance(); 

    @FXML 
    private View       view; 

    @FXML 
    private ListView<String>    lview; 

    private Button       btnBack; 
    private Button       btnMoreMenu; 
    private TextField      txtSearch; 

    private boolean      firstShow = true; 

    private ObservableList<String>   items = createItems(); 

    @FXML 
    protected void initialize() { 
     view.setOnShowing(e -> onShowing()); 
     view.setOnShown(e -> onShown()); 

     btnBack = MaterialDesignIcon.ARROW_BACK.button(e -> app.goHome()); 
     btnMoreMenu = MaterialDesignIcon.MORE_VERT.button(); 
     txtSearch = new TextField("Items"); 
     txtSearch.setPromptText("search"); 

     lview.setPlaceholder(new Label("no data to display")); 
    } 

    private void onShowing() { 
     app.getAppBar().setNavIcon(btnBack); 
     app.getAppBar().setTitle(txtSearch); 
     app.getAppBar().getActionItems().add(btnMoreMenu); 
    } 

    private void onShown() { 
     if (!firstShow) { 
      lview.setItems(items); 

     } else { 
      firstShow = false; 
      lview.setPlaceholder(new Label("loading data...")); 

      Platform.runLater(() -> { 
       try { 
        Thread.sleep(2000); //to simulate a long lasting initial creation of listCells 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       lview.setItems(items); 
      }); 
     } 
    } 

    private ObservableList<String> createItems() { 
     ObservableList<String> items = FXCollections.observableArrayList(); 
     String name = "Person #"; 

     for (int i = 0; i < 20; i++) { 
      items.add(name + i); 
     } 

     return items; 
    } 
} 


<View fx:id="view" id="itemsView" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="com.jns.appbartest.view.ItemsPresenter"> 
    <center> 
     <MobileLayoutPane fx:id="pneListView"> 
      <center> 
       <ListView fx:id="lview" /> 
      </center> 
     </MobileLayoutPane> 
    </center> 
</View> 
+0

問題を再現できません。 ListViewを使って簡単なテストを作成しました。項目が表示される前にテキストフィールドテキストまたはプロンプトテキストが正しく表示されているのがわかりました。 –

+0

問題を再現するためのコードを追加しました – jns

答えて

0

、私はAndroid上で問題を再現することができます。

はもちろん、私はこの部分を取る:

private void onShown() { 
    lview.setPlaceholder(new Label("loading data...")); 
    Platform.runLater(() -> { 
     try { 
      Thread.sleep(2000); //to simulate a long lasting initial creation of listCells 
     } catch (InterruptedException e) { } 
     lview.setItems(items); 
    }); 
} 

は、細胞の初期作成をシミュレートするために追加されます。

しかし、正確には、あなたが直面している問題を示しています。疑似サンプルは、JavaFXスレッド(Platform.runLater)でブロックしていることを示しています(Thread.sleep(2000))。その間、textFieldテキストは黒で、後でそれだけがスタイルになります。

あなたはこの1つにそのスニペットを変更する場合:

private void onShown() { 
    lview.setPlaceholder(new Label("loading data...")); 
    new Thread(new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
      try { 
       Thread.sleep(2000); //to simulate a long lasting initial creation of listCells 
      } catch (InterruptedException e) { } 
      return null; 
     } 

     @Override 
     protected void succeeded() { 
      lview.setItems(items); 
     } 
    }).start(); 
} 

今重いタスクはJavaFXのスレッドの外にある、そしてあなたは、TextFieldがすぐにスタイル設定されていることがわかります。

あなたの本当の問題に戻る:ここで教訓は、重い作業のたびにJavaFXスレッドから抜け出し、最後の瞬間にしか呼び出さないことです。 Taskはそうするための良い仕組みです。

+0

私のアプリケーションでは、プリロードが表示されている間、appstartで初期化されたキャッシュからアイテムを取得します。 ListCellが作成されるとUIがしばらくブロックされているようです。私は、最初にListViewにfixedCellSizeを設定することでスピードを向上させることができましたが、顕著な遅延が残っています。モックの例でも、ボタンにCSSが適用され、TextFieldのスタイルが後で変更される可能性はありますか? – jns

+1

デスクトップ上で実行すると、AppBarにノードが表示されないので、UIは完全にフリーズします。それが期待される結果です。 Androidでは、UIをブロックするのに時間がかかり、その短期間にノードが追加され、部分的にスタイリングされます。これを念頭に置いて、セルの作成を少し遅らせることができれば、ビューを適切にレンダリングしますが、フルロードを完了するまでには時間がかかります。 –

+0

私はデスクトップ上で実行すると、すべての正常に見えます。 AppBarは、適切にスタイルされたすべてのノードを表示します。高速テストのために、PauseTransitionを使用してセルの作成を遅らせ、問題を解決しました。ありがとう。私は遅れのための適切な持続時間が何であるか疑問に思うだけですか? – jns

関連する問題