Text input on Android: toggle soft keyboard
Hi, I am trying to port a project i am working on to Android (a little programming environment based on Lua + Dear Imgui). imgui_bundle looks fantastic to do that !
Maybe i am missing something, but the soft keyboard doesn't toggle when it needs to. I have tested with imgui_bundle_template, added an ImGuiColorTextEdit widget, and an InputTextMultiline.
I've managed to get it working (with the help of chatGPT... because android is not really my cup of tea :s). If you want i can share the little piece of code (a java method to toggle the keyboard, and a jni wrapper to call it). But you will probably come up with something better !
imgui_bundle_template commit : 771fb9e103a39b60713a275f2142dabab604eff0 imgui_bundle commit : 55b2cd34efaf740cddf17c0141c710b3abf84d43
platform : Debian testing, compiling for android language : C++ compiler: gcc 15.2.0 backend : SDL2 + OpenGL
btw, thank you very much for your online imgui manual. i use it all the time !
Hi,
Thanks for your message. Actually, Android is not my cup of tea either. I'd be interested if you are willing to share a working piece of code to toggle the keyboard.
Thanks!
Here is my code. It would have been better to make a pull request maybe, but i don't know where is the best place to put each part. And the java file i needed to edit (imguibundleexampleintegration.java) is generated. I hope this is helpful.
diff --git a/hello_world.cpp b/hello_world.cpp
index 6287d93..7d4cb62 100644
--- a/hello_world.cpp
+++ b/hello_world.cpp
@@ -7,6 +7,23 @@
#include <cmath>
+#ifdef __ANDROID__
+#include <jni.h>
+#include <SDL.h>
+#include <SDL_system.h>
+
+void ShowAndroidKeyboard()
+{
+ JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
+ jobject activity = (jobject)SDL_AndroidGetActivity();
+ jclass clazz = env->GetObjectClass(activity);
+ jmethodID method_id = env->GetMethodID(clazz, "ShowAndroidKeyboard", "()V");
+ if (method_id)
+ env->CallVoidMethod(activity, method_id);
+ env->DeleteLocalRef(activity);
+ env->DeleteLocalRef(clazz);
+}
+#endif
void DemoImplot()
{
@@ -32,6 +49,10 @@ void DemoImplot()
ImPlot::EndPlot();
}
#endif
+
+ static char buf[1024];
+ ImGui::InputTextMultiline("InputTextMultiline", buf, sizeof(buf));
+
}
@@ -63,14 +84,34 @@ int main(int , char *[])
HelloImGui::SetAssetsFolder(ASSETS_LOCATION);
#endif
- HelloImGui::SimpleRunnerParams runnnerParams;
- runnnerParams.guiFunction = Gui;
- runnnerParams.windowSize = {600, 800};
+ HelloImGui::SimpleRunnerParams simpleRunnerParams;
+ simpleRunnerParams.guiFunction = Gui;
+ simpleRunnerParams.windowSize = {600, 800};
+
+#ifdef __ANDROID__
+ HelloImGui::RunnerParams runnerParams = simpleRunnerParams.ToRunnerParams();
+ runnerParams.callbacks.AfterSwap = []() {
+ static bool keyboardVisible = false;
+ bool wantText = ImGui::GetIO().WantTextInput;
+ if(wantText && !keyboardVisible) {
+ SDL_StartTextInput();
+ ShowAndroidKeyboard();
+ keyboardVisible = true;
+ } else if(!wantText && keyboardVisible) {
+ SDL_StopTextInput();
+ keyboardVisible = false;
+ }
+ };
+#endif
ImmApp::AddOnsParams addOnsParams;
addOnsParams.withMarkdown = true;
addOnsParams.withImplot = true;
- ImmApp::Run(runnnerParams, addOnsParams);
+#ifdef __ANDROID__
+ ImmApp::Run(runnerParams, addOnsParams);
+#else
+ ImmApp::Run(simpleRunnerParams, addOnsParams);
+#endif
return 0;
}
And the "ShowAndroidKeyboard" function in imguibundleexampleintegration.java :
package com.helloimgui.imguibundleexampleintegration;
import android.view.inputmethod.InputMethodManager;
import android.content.Context;
import org.libsdl.app.SDLActivity;
/**
* A sample wrapper class that just calls SDLActivity
*/
public class imguibundleexampleintegration extends SDLActivity
{
/**
* This method is called by SDL before loading the native shared libraries.
* It can be overridden to provide names of shared libraries to be loaded.
* The default implementation returns the defaults. It never returns null.
* An array returned by a new implementation must at least contain "SDL2".
* Also keep in mind that the order the libraries are loaded may matter.
* @return names of shared libraries to be loaded (e.g. "SDL2", "main").
*/
protected String[] getLibraries() {
return new String[] {
// "hidapi",
"SDL2",
// "SDL2_image",
// "SDL2_mixer",
// "SDL2_net",
// "SDL2_ttf",
"imgui_bundle_example_integration"
};
}
public void ShowAndroidKeyboard() {
InputMethodManager imm = null;
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
}
}
/*
This code was generated from apkCMake_activityClassName.java
and will be placed in the appropriate folder.
You can customize your application id via
* ${apkCMake_applicationIdUrlPart}
* ${apkCMake_applicationIdNamePart}
* ${apkCMake_activityClassName}
For example, if:
* apkCMake_applicationIdUrlPart=com.my_company
* apkCMake_applicationIdNamePart=my_app
* apkCMake_activityClassName=MyApp
then a file MyApp.java will be created into
app/src/main/java/com/my_company/my_app/MyApp.java
*/
Thanks, I labeled this as a faq issue, so that other users can find it.