In my game, when a textfield is touched, the view moves up along with the keyboard.
Here's the code in AndroidLauncher:
onCreate(){
//other codes...
setListenerToRootView()
}
private fun setListenerToRootView() {
val activityRootView: View = window.decorView.findViewById(content)
activityRootView.viewTreeObserver.addOnGlobalLayoutListener(keyboardLayoutListener)
}
private var keyboardLayoutListener: OnGlobalLayoutListener? = OnGlobalLayoutListener {
val visibleDisplayFrame = Rect()
window.decorView.getWindowVisibleDisplayFrame(visibleDisplayFrame)
sizeChanged(visibleDisplayFrame.width(), visibleDisplayFrame.height())
}
override fun sizeChanged(width: Int, height: Int) {
val heightRatio = Gdx.graphics.height / main.worldHeight
val worldHeightChanged = height / heightRatio
val keyboardStatus = if (height == Gdx.graphics.height) KeyboardStatus.HIDE else KeyboardStatus.SHOW
main.platformsObservable.notifyObservers(Triple(ObservableKeys.SCREEN_SIZE_CHANGED, keyboardStatus, worldHeightChanged))
log.error("SCREEN_SIZE_CHANGED, status = $keyboardStatus")
}
The above code gets the keyboard height and status to send to my libgdx game class for the Camera to move the screen up/down.
With a normal keyboard it would send something like this for when the keyboard is shown:
SCREEN_SIZE_CHANGED, status = SHOW
and when the keyboard is hidden:
SCREEN_SIZE_CHANGED, status = HIDE
But on Samsung devices with the keyboard id of "com.samsung.android.honeyboard/.service.HoneyBoardService" then it does all this when the keyboard is shown once:
SCREEN_SIZE_CHANGED, status = HIDE
SCREEN_SIZE_CHANGED, status = SHOW
SCREEN_SIZE_CHANGED, status = SHOW
SCREEN_SIZE_CHANGED, status = SHOW
And this is making the keyboard blocking the textfield in my game because the view doesn't move up.
My gdxVersion is 1.11.0
How can I fix this?
Hi This isn't a libGDX issue. You need to provide parameters to your activity specifically saying what you want for this value (being the screen keyboard as opposed to a hardware one)
android:windowSoftInputMode
as described here
https://developer.android.com/guide/topics/manifest/activity-element.html#wsoft
and consider what you want for the parameters
adjustResize
adjustPan
Related
I have a simple screen implemented with Jetpack Compose,
here is a preview of the screen.
There is a button like the sun on the TopAppBar which the user clicks to take a screenshot.
The problem is that I want to show the screenshot of the entire screen but without showing the status bar and the navigation bar.
Is there a solution to do this?
The composables are tied to a View which you can access with LocalView.current and through that View you can retrieve its .context and through that you can get to its Activity and to the Window object.
Once you have a reference to the Window (and to the View, if you have to support API level lower than 30), you can control status bar and navigation bar visibility.
A code example:
#Composable
fun MyFullScreenComposable() {
val view = LocalView.current
SideEffect {
requestFullScreen(view)
}
Box {
// ... other content
Button(
onClick = { requestFullScreen(view) }
) {
Text("Go fullscreen")
}
}
}
fun requestFullScreen(view: View) {
// !! should be safe here since the view is part of an Activity
val window = view.context.getActivity()!!.window
WindowCompat.getInsetsController(window, view).hide(
WindowInsetsCompat.Type.statusBars() or
WindowInsetsCompat.Type.navigationBars()
)
}
fun Context.getActivity(): Activity? = when (this) {
is Activity -> this
// this recursion should be okay since we call getActivity on a view context
// that should have an Activity as its baseContext at some point
is ContextWrapper -> baseContext.getActivity()
else -> null
}
In your case you might have to hide your action/title bar as well (or maybe you are already doing that).
Note that when the user taps on the screen while in full-screen mode, the bars will slide back. That's why I added a button as an example how you can let the user go back into full-screen mode through an action. In your case that could be a FloatingActionButton or some action on a semi-transparent top action bar.
I am running a foreground service which shows a system overlay. I want to detect change in status bar visibility.
So for example, if any video is being watched or any game is being played, the running activity is in full screen mode and status bar is hidden. But when a user swipes from top or any notification arrives, the status bar is visible.
I want to detect this changes in the status bar's visibility.
I have gone through this another post which discussed a similar use case. Not much help.
Detect Status Bar Visibility / TYPE_SYSTEM_OVERLAY not resizing automatically
I am using the code below to inflate my system overlay
private fun setupListenerToDetectStatusBar() {
val p = WindowManager.LayoutParams()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
p.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
else
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
p.gravity = Gravity.RIGHT or Gravity.TOP
p.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
p.width = 1
p.height = ViewGroup.LayoutParams.MATCH_PARENT
p.format = PixelFormat.OPAQUE
helperWnd = View(ctx) //View helperWnd;
windowManager.addView(helperWnd, p)
Log.d("status-bar", "added-global-layout listener")
helperWnd?.viewTreeObserver?.addOnGlobalLayoutListener(layoutListener)
helperWnd?.setBackgroundColor(Color.BLACK)
helperWnd?.setOnSystemUiVisibilityChangeListener{
Log.d("status-bar", "UI visibility: $it $isFullScreen")
}
}
The GlobalLayoutListener is ineffective and doesn't detect any change while the systemUIVisibilityListener, however deprecated, detects the app going full screen either when the app is launched or the notification shade is open and closed.
I also tried detecting this by using Accessibility service.
The change in the visibility of status bar is not being detected by any of the methods.
I am able to detect all the other the events in the service.
val LOG_TAG = "MyAccessibilityService"
var recordScreen = false
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
event?.let {
var canIgnore = false
val eventPackage = it.packageName
logger.log("onAccessibilityEvent: A event package $eventPackage")
}
}
Is there any other way this can be achieved?
I have in my setting the option which should disable the app soft keyboard as some users could have a device with physical keyboard.
The issue is that everything i'm trying is not working and the soft keyboard is shown anyway,
I've tryed:
adding android:windowSoftInputMode="stateAlwaysHidden" in my manifest, i've tryed the following code in my fragment:
fun hideKeyboard(activity: Activity) {
val imm: InputMethodManager =
activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
//Find the currently focused view, so we can grab the correct window token from it.
var view = activity.currentFocus
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = View(activity)
}
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
which i called in onViewCreated like:
hideKeyboard(requireActivity())
I've set to all EditText showSoftInputOnFocus:
val keyboard = prefs.getBoolean("keyboard", true)
txtBarcode.showSoftInputOnFocus = keyboard
txtQta.showSoftInputOnFocus = keyboard
And when showSoftInputOnFocus is set the keyboard doen't appear, but once i type something with the physical keyobard the softkeyboard is shown...
So based on my setting keyboard value (true,false) how can i disable the softkeyboard for the whole applicaiton??
`
constructor: function() {
this.adjustHeight = Ext.Function.createBuffered(function(textarea) {
var textAreaEl = textarea.getComponent().input;
if (textAreaEl) {
textAreaEl.dom.style.height = 'auto';
var iNewHeight = textAreaEl.dom.scrollHeight;
if (iNewHeight > 0) {
textAreaEl.dom.style.height = textAreaEl.dom.scrollHeight + "px";
}
}
},200,this);
this.callParent(arguments);
}
I want the textarea focused with full content visible . But text area hiding with keypad
Try to use the onBeforeFocus event with scrolling:
scrollableView.scrollTo(textfield.element.getXY()[0],textfield.element.getXY()[1]);
And now you might want to do this to all textfields and textareafields, so that the user gets the same on all items.
Make sure, that the effect is either earlier than the keypad animation or delay it with about 175ms.
Ext.defer(function() {###your code goes here###}, 175, this);
I have footer bar in my activity. I used fragment for footer bar. here is screen shot. . When I add the text into the EditText, the keyboard show like this. . I would like to hide the footer when the keyboard appear. I used android:windowSoftInputMode="adjustPan" in activity. I would like to know any suggestion.
Thanks.
i have faced same situation, and dont have finded any solution,so just started another activity on touch of textview. on completion of activity again in this activity gotted result back from the textview of next activity and placed the text in current activity's textview. it works
i got the same problem i just removed android:windowSoftInputMode="adjustPan" from my manifest file and i got the desired output
var originalHeight = document.documentElement.clientHeight;
var originalWidth = document.documentElement.clientWidth;
$(window).resize(function() {
// Control landscape/portrait mode switch
if (document.documentElement.clientHeight == originalWidth &&
document.documentElement.clientWidth == originalHeight) {
originalHeight = document.documentElement.clientHeight;
originalWidth = document.documentElement.clientWidth;
}`enter code here`
// Check if the available height is smaller (keyboard is shown) so we hide the footer.
if (document.documentElement.clientHeight < originalHeight) {
$('.footer').hide();
} else {
$('.footer').show();
}
});
try this it will work and give class="footer"