2016-11-25 70 views
3

我在底部的容器(VBox)中有一個TextField。當我選擇TextField輸入一些文本時,它會隱藏在鍵盤(iPhone)後面。我把VBox放在ScrollPane中,但仍然一樣。容器中的TextField - 鍵盤隱藏文本

我可以通過鍵盤獲得它的高度嗎?我如何放置沒有從鍵盤覆蓋的TextFields?

謝謝你的幫助。

回答

3

此時,JavaFX或JavaFXPorts中沒有內置方法來獲取(本地)iOS軟鍵盤。

的解決方案,使鍵盤和找出是否有任何節點,就像一個TextField會被它覆蓋,就需要從那些在膠子的魅力下library可用Service,但現在沒有這樣的KeyboardService

基於像this這樣的原生解決方案,當顯示或隱藏鍵盤時很容易得到通知。所以我們可以利用這些監聽器並將高度值發送回JavaFX圖層。

因此,讓我們創建KeyboardService,考慮如何在Charm Down庫中創建服務。

由於這裏有點超出範圍,所以我創建了這個帶有所需文件的gist

按照以下步驟,使其工作:

  1. 創建一個膠子工程

創建一個膠子項目(單個視圖)與你的IDE最新版本的膠子插件。

  • 添加KeyboardService接口
  • 添加包com.gluonhq.charm.down.plugins。添加類KeyboardServicelink)和KeyboardServiceFactorylink)。

    public interface KeyboardService { 
        public ReadOnlyFloatProperty visibleHeightProperty(); 
    } 
    
  • 的iOS實施
  • 根據iOS包添加了iOS執行服務IOSKeyboardServicelink)的。

    public class IOSKeyboardService implements KeyboardService { 
    
        static { 
         System.loadLibrary("Keyboard"); 
         initKeyboard(); 
        } 
    
        private static ReadOnlyFloatWrapper height = new ReadOnlyFloatWrapper(); 
    
        @Override 
        public ReadOnlyFloatProperty visibleHeightProperty() { 
         return height.getReadOnlyProperty(); 
        } 
    
        // native 
        private static native void initKeyboard(); 
    
        private void notifyKeyboard(float height) { 
         Platform.runLater(() -> this.height.setValue(height)); 
        } 
    
    } 
    
  • 本地代碼
  • /src/ios下創建native文件夾,並添加Keyboard.hlink)文件:

    #import <UIKit/UIKit.h> 
    #include "jni.h" 
    
    @interface Keyboard : UIViewController {} 
    @end 
    
    void sendKeyboard(); 
    

    Keyboard.mlink)file:

    static int KeyboardInited = 0; 
    jclass mat_jKeyboardServiceClass; 
    jmethodID mat_jKeyboardService_notifyKeyboard = 0; 
    Keyboard *_keyboard; 
    CGFloat currentKeyboardHeight = 0.0f; 
    
    JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSKeyboardService_initKeyboard 
    (JNIEnv *env, jclass jClass) 
    { 
        if (KeyboardInited) 
        { 
         return; 
        } 
        KeyboardInited = 1; 
    
        mat_jKeyboardServiceClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/gluonhq/charm/down/plugins/ios/IOSKeyboardService")); 
        mat_jKeyboardService_notifyKeyboard = (*env)->GetMethodID(env, mat_jKeyboardServiceClass, "notifyKeyboard", "(F)V"); 
        GLASS_CHECK_EXCEPTION(env); 
    
        _keyboard = [[Keyboard alloc] init]; 
    } 
    
    void sendKeyboard() { 
        GET_MAIN_JENV; 
        (*env)->CallVoidMethod(env, mat_jKeyboardServiceClass, mat_jKeyboardService_notifyKeyboard, currentKeyboardHeight); 
    } 
    
    @implementation Keyboard 
    
    - (void) startObserver 
    { 
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 
    } 
    
    - (void) stopObserver 
    { 
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 
    } 
    
    - (void)keyboardWillShow:(NSNotification*)notification { 
        NSDictionary *info = [notification userInfo]; 
        CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; 
        currentKeyboardHeight = kbSize.height; 
        sendKeyboard(); 
    } 
    
    - (void)keyboardWillHide:(NSNotification*)notification { 
        currentKeyboardHeight = 0.0f; 
        sendKeyboard(); 
    } 
    
    @end 
    

  • 構建本地庫
  • 在Mac上使用最新版本的Xcode,你可以建立本地庫libKeyboard.a。爲此,您需要將xcodebuild任務添加到項目的build.gradle文件(link)。它基於Charm Down的ios-build.gradlefile

    task xcodebuild { 
        doLast { 
         xcodebuildIOS("$project.buildDir","$project.projectDir", "Keyboard") 
        } 
    } 
    

    保存您的項目,並從項目根目錄下的命令行運行./gradlew clean build xcodebuild

    如果一切都已到位,您應該在build/native下找到libKeyboard.a。複製該文件,在src/ios下創建文件夾jniLibs,然後將其粘貼到那裏。

  • 實現服務
  • 添加TextFieldBasicView,改變對準BOTTOM-CENTER

    VBox controls = new VBox(15.0, label, button, new TextField()); 
    controls.setAlignment(Pos.BOTTOM_CENTER); 
    

    實現服務:

    Services.get(KeyboardService.class).ifPresent(keyboard -> { 
        keyboard.visibleHeightProperty().addListener((obs, ov, nv) -> 
         setTranslateY(-nv.doubleValue())); 
    }); 
    
  • 部署和運行
  • 您應該一切準備就緒。插入你的iPhone/iPad,並運行./gradlew --info launchIOSDevice

    當文本框獲得焦點,軟鍵盤顯示出來,並且認爲是翻譯,所以文本字段是完全可見:

    希望這項服務將在一些被列入魅力向下點。但這也是您如何添加自定義服務的一個很好的例子。另外請注意,Charm Down項目是開源的,所以任何貢獻都是很好的。

    +0

    太棒了!謝謝!! – tonimaroni

    +0

    嘿何塞。我今天才發現時間來實現上面的插件。完美描述和一切工作。 我有一個「發送」按鈕右邊的文本框。上面的解決方案,我必須按「發送」兩次。第一次它刪除鍵盤..然後我必須再次點擊按鈕才能完成他的工作。你有什麼想法我需要改變,所以當鍵盤處於活動狀態時,按下一個按鈕將首次觸發。謝謝。 – tonimaroni

    +0

    用'button.setOnMouseClicked()'替換'button.setOnAction()',應該可以。不知何故''fire()'事件被消耗,當鍵盤被解散和'onAction'沒有被觸發。 –