瀏覽代碼

Merge pull request #40671 from nekomatata/virtual-keyboard-height-fix

Fix virtual keyboard height regression
Rémi Verschelde 5 年之前
父節點
當前提交
6de86946ea

+ 35 - 5
platform/android/java/lib/src/org/godotengine/godot/Godot.java

@@ -70,6 +70,7 @@ import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.provider.Settings.Secure;
 import android.view.Display;
+import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -82,6 +83,7 @@ import android.view.Window;
 import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.FrameLayout;
+import android.widget.PopupWindow;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
@@ -163,6 +165,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
 	public GodotRenderView mRenderView;
 	private boolean godot_initialized = false;
 
+	private PopupWindow mKeyboardWindow;
+
 	private SensorManager mSensorManager;
 	private Sensor mAccelerometer;
 	private Sensor mGravity;
@@ -219,11 +223,23 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
 		containerLayout = new FrameLayout(activity);
 		containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 
+		// Create a popup window with an invisible layout for the virtual keyboard,
+		// so the view can be resized to get the vk height without resizing the main godot view.
+		final FrameLayout keyboardLayout = new FrameLayout(activity);
+		keyboardLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+		keyboardLayout.setVisibility(View.INVISIBLE);
+		mKeyboardWindow = new PopupWindow(keyboardLayout, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+		mKeyboardWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+		mKeyboardWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+		mKeyboardWindow.setFocusable(true); // for the text edit to work
+		mKeyboardWindow.setTouchable(false); // inputs need to go through
+
 		// GodotEditText layout
 		GodotEditText editText = new GodotEditText(activity);
-		editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-		// ...add to FrameLayout
-		containerLayout.addView(editText);
+		editText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+		editText.setKeyboardView(keyboardLayout);
+		// ...add to keyboard layout
+		keyboardLayout.addView(editText);
 
 		GodotLib.setup(command_line);
 
@@ -240,13 +256,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
 		editText.setView(mRenderView);
 		io.setEdit(editText);
 
-		view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+		keyboardLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 			@Override
 			public void onGlobalLayout() {
 				Point fullSize = new Point();
 				activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
 				Rect gameSize = new Rect();
-				mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
+				mKeyboardWindow.getContentView().getWindowVisibleDisplayFrame(gameSize);
 
 				final int keyboardHeight = fullSize.y - gameSize.bottom;
 				GodotLib.setVirtualKeyboardHeight(keyboardHeight);
@@ -603,8 +619,22 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
 		return containerLayout;
 	}
 
+	@Override
+	public void onStart() {
+		super.onStart();
+
+		mRenderView.getView().post(new Runnable() {
+			@Override
+			public void run() {
+				mKeyboardWindow.showAtLocation(getActivity().getWindow().getDecorView(), Gravity.NO_GRAVITY, 0, 0);
+			}
+		});
+	}
+
 	@Override
 	public void onDestroy() {
+		mKeyboardWindow.dismiss();
+
 		for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
 			plugin.onMainDestroy();
 		}

+ 8 - 2
platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java

@@ -39,6 +39,7 @@ import android.text.InputFilter;
 import android.text.InputType;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
+import android.view.View;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
@@ -56,6 +57,7 @@ public class GodotEditText extends EditText {
 	// Fields
 	// ===========================================================
 	private GodotRenderView mRenderView;
+	private View mKeyboardView;
 	private GodotTextInputWrapper mInputWrapper;
 	private EditHandler sHandler = new EditHandler(this);
 	private String mOriginText;
@@ -129,7 +131,7 @@ public class GodotEditText extends EditText {
 
 					edit.mInputWrapper.setOriginText(text);
 					edit.addTextChangedListener(edit.mInputWrapper);
-					final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+					final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 					imm.showSoftInput(edit, 0);
 				}
 			} break;
@@ -138,7 +140,7 @@ public class GodotEditText extends EditText {
 				GodotEditText edit = (GodotEditText)msg.obj;
 
 				edit.removeTextChangedListener(mInputWrapper);
-				final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+				final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 				imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
 				edit.mRenderView.getView().requestFocus();
 			} break;
@@ -162,6 +164,10 @@ public class GodotEditText extends EditText {
 		view.getView().requestFocus();
 	}
 
+	public void setKeyboardView(final View keyboardView) {
+		mKeyboardView = keyboardView;
+	}
+
 	// ===========================================================
 	// Methods for/from SuperClass/Interfaces
 	// ===========================================================