我在底部的容器(VBox)中有一個TextField。當我選擇TextField輸入一些文本時,它會隱藏在鍵盤(iPhone)後面。我把VBox放在ScrollPane中,但仍然一樣。容器中的TextField - 鍵盤隱藏文本
我可以通過鍵盤獲得它的高度嗎?我如何放置沒有從鍵盤覆蓋的TextFields?
謝謝你的幫助。
我在底部的容器(VBox)中有一個TextField。當我選擇TextField輸入一些文本時,它會隱藏在鍵盤(iPhone)後面。我把VBox放在ScrollPane中,但仍然一樣。容器中的TextField - 鍵盤隱藏文本
我可以通過鍵盤獲得它的高度嗎?我如何放置沒有從鍵盤覆蓋的TextFields?
謝謝你的幫助。
此時,JavaFX或JavaFXPorts中沒有內置方法來獲取(本地)iOS軟鍵盤。
的解決方案,使鍵盤和找出是否有任何節點,就像一個TextField
會被它覆蓋,就需要從那些在膠子的魅力下library可用Service
,但現在沒有這樣的KeyboardService
。
基於像this這樣的原生解決方案,當顯示或隱藏鍵盤時很容易得到通知。所以我們可以利用這些監聽器並將高度值發送回JavaFX圖層。
因此,讓我們創建KeyboardService
,考慮如何在Charm Down庫中創建服務。
由於這裏有點超出範圍,所以我創建了這個帶有所需文件的gist。
按照以下步驟,使其工作:
創建一個膠子項目(單個視圖)與你的IDE最新版本的膠子插件。
添加包com.gluonhq.charm.down.plugins
。添加類KeyboardService
(link)和KeyboardServiceFactory
(link)。
public interface KeyboardService {
public ReadOnlyFloatProperty visibleHeightProperty();
}
根據iOS包添加了iOS執行服務IOSKeyboardService
(link)的。
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.h
(link)文件:
#import <UIKit/UIKit.h>
#include "jni.h"
@interface Keyboard : UIViewController {}
@end
void sendKeyboard();
和Keyboard.m
(link)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.gradle
file。
task xcodebuild {
doLast {
xcodebuildIOS("$project.buildDir","$project.projectDir", "Keyboard")
}
}
保存您的項目,並從項目根目錄下的命令行運行./gradlew clean build xcodebuild
。
如果一切都已到位,您應該在build/native
下找到libKeyboard.a
。複製該文件,在src/ios
下創建文件夾jniLibs
,然後將其粘貼到那裏。
添加TextField
到BasicView
,改變對準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項目是開源的,所以任何貢獻都是很好的。
太棒了!謝謝!! – tonimaroni
嘿何塞。我今天才發現時間來實現上面的插件。完美描述和一切工作。 我有一個「發送」按鈕右邊的文本框。上面的解決方案,我必須按「發送」兩次。第一次它刪除鍵盤..然後我必須再次點擊按鈕才能完成他的工作。你有什麼想法我需要改變,所以當鍵盤處於活動狀態時,按下一個按鈕將首次觸發。謝謝。 – tonimaroni
用'button.setOnMouseClicked()'替換'button.setOnAction()',應該可以。不知何故''fire()'事件被消耗,當鍵盤被解散和'onAction'沒有被觸發。 –