I am attempting to use a swipe gesture to finish a fragment, and if the fragment is displaying the keyboard, the keyboard will be hidden. The following is a sample:
public void finishFragment() {
View focus = getCurrentFocus();
InputMethodManager imm = null;
if (focus != null) {
imm = (InputMethodManager) focus.getContext().
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
imm.hideSoftInputFromWindow(focus.getWindowToken(), 0);
}
}
if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
}
}
Unfortunately, since I am calling a service along side the fragment stack, the service is hanging up the UI display, thus giving it a laggy appearance. Does anyone know how I can hide the keyboard without calling a service or should I call an Async process? Even better, does anyone know how onBackPressed() removes the keyboard?
There are only 2 ways to control the keyboard on Android:
Programmatically with the InputMethodManager like you are doing (which will as far as I know always requires you to call .getSystemService() to use)
Using android:windowSoftInputMode="X" to specify the behavior of the keyboard in the context of the given activity tag in the AndroidManifest
So to answer your questions of: "Does anyone know how I can hide the keyboard without calling a service"? You could do the following in the AndroidManifest, where ActivityX is the activity you want to have this type of behavior.
AndroidManifest.xml:
<activity
android:name="com.namespace.of.ActivityXYZ"
android:windowSoftInputMode="stateHidden" />
This will serve to hide the keyboard initially for ActivityX, but I am not sure if this will give you the desired behavior/lack of laggyness when swiping to finish the fragment. Also try changing "stateHidden" to "stateAlwaysHidden" or "stateUnchanged". Checkout what these do here if you do not know.
Another approach would be: instead of checking the focus and getting the keyboard programmatically like you are doing, why not just finish() the activity managing the fragment you wish to end? This will also hide the keyboard if it was open.
Hope this helps!
Related
I have an AppCompatActivity where I programmatically toggle the softinput. There is only one scenario where my keyboard open/close boolean is not set properly because I cannot intercept the back-button event. This event closes the keyboard when executed.
The following is printed when pressing the on-screen back button when a keyboard is opened.
I/ViewRootImpl#af03171[MainActivity]: The input has been finished in ImeInputStage.
I've tried all the toggleSoftInput variants/flags I could find to pray it would somehow circumvent the issue
I tried to catch the press with "dispatchKeyEvent", "backPressed", "onKeyUp", "onKeyDown", "onKeyPreIme" with no luck.
And as the message says the event is finishing somewhere else. I just can't find anything on the web to realize the functionality I need for my application.
In addition, this is my toggle function.
public void toggleSoftInput() {
InputMethodManager imm = (InputMethodManager) getAndroidContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
keyboardOpened = !keyboardOpened;
}
Edit: I've searched over any resource I could find and still haven't been able to resolve this edge case in my application. Any pointers are greatly appreciated.
I came across this piece of code but I am wondering what this code does and what exactly is InputMethodManager and where should I type in this code in my class? Will it go in the onCreate() method or should I make a new method? And again, I want to understand how this method works.
Thanks for your answer in advance :) I appreciate the help
InputMethodManager inputManager =
(InputMethodManager) context.
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(
this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
The javadoc of InputMethod is quite descriptive about it
Central system API to the overall input method framework (IMF) architecture, which arbitrates interaction between applications and the current input method. You can retrieve an instance of this interface with Context.getSystemService().
In your particular case you are interseted in this use case
An input method (IME) implements a particular interaction model allowing the user to generate text. The system binds to the current input method that is use, causing it to be created and run, and tells it when to hide and show its UI. Only one IME is running at a time.
Also from the description of hideSoftInputFromWindow you can extract
public boolean hideSoftInputFromWindow (IBinder windowToken, int flags)
Synonym for hideSoftInputFromWindow(IBinder, int, ResultReceiver) without a result: request to hide the soft input window from the context of the window that is currently accepting input.
Parameters
windowToken IBinder: The token of the window that is making the request, as returned by View.getWindowToken().
flags int: Provides additional operating flags. Currently may be 0 or have the HIDE_IMPLICIT_ONLY bit set.
This makes this in your code refer to a View, so that code is part of a class that extends View
Here is an example of its usage.
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
I want to create an activity that will hide the keyboard. The activity will keep on running in the background as a service and prevent the keyboard from being visible for all the apps. As in the keyboard will not come up unless the activity is stopped. Can anyone point me towards the correct source?
put below code in your manifest file:
<activity
android:name=".View.ViewRegistration"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="stateHidden" />
I hope its useful to you.and you can call below method in every activity onresume() and onPause().
public static void hideKeyboard(final Activity activity) {
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (activity.getCurrentFocus() != null) {
inputManager.hideSoftInputFromWindow(activity.getCurrentFocus()
.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
An Activity can not just be kept "running in the background as a service".
From the documentation:
An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you...
You would need to create an Service. I haven't tried hiding the keyboard via a service, but a wild guess is, that it isn't possible.
A solution could be to create your own keyboard, that the user would then need to switch to.
You can add this one line of code in your manifest for all those activities where you need to hide the keyboard:
android:windowSoftInputMode="stateHidden"
For example:
<activity
android:name="com.example.yourappname.MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
>
I have a ListFragment which opens an Activity when it is clicked. Now, my problem is that my listener is lost when the screen is rotated. The click events does not respond. I have tried android:configChanges , it fixes the listener problem but the layout of the whole activity looks weird. Any possible solutions to set listener again on configuration change?
Best solution: The better way to handle the problem by using onSaveInstanceState().see this link Handling Runtime Changes
No.2: You can detect the change and then handle it through the below method:
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
// Checks the orientation
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape mode", Toast.LENGTH_SHORT).show();
} else if (config.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait mode", Toast.LENGTH_SHORT).show();
}
}
The forced solution: if you don't want to recycle the activity lifecycle on orientation change then you can add this in your manifest:
<activity android:name=".YourActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
The last one is the worst solution, but works.
As my suggestion never use the last one because you can't able to do any kind of recycle things in future. but for emergency solution its good.
After logout the user is directed to login screen in android. Now, if user clicks on back button of phone it should stay on login screen itself.
How can I make it possible in android?
I have used following code in my application but it will close my application. It should stay on the login screen only
Intent objsignOut = new Intent(getBaseContext(),Hello.class);
objsignOut.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(objsignOut);
Please guide me the correct way.
override the onBackPressed in your login activity, to do nothing..
public void onBackPressed() {
//do nothing
}
It seems to me that there are simpler and cleaner solutions than overriding onBackPressed method, as mentioned here and here.
You can provide flags when launching a new activity (on login or logout) to simply clear the "back-stack" rather than override the behavior for the back-button:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
This is a safer solution that can also be used after you log-in and not just after you log-out.
public void onBackPressed(){
if(appCanClose){
finish();
}
}
These functions can exist in both the system framework (used if not in your code), as well as in your code. If you leave it empty, the app will do nothing when the back button gets pressed.
In this example, when the boolean value appCanClse is true, the back button will quit the app, if false, the back button wil do nothing. I would make sure the user still has someway to quit the app. :p
You can do it by just adding this two line of codes
#Override
public void onBackPressed(){
moveTaskToBack(true);
}
It will prevent going back to previous activity as well as take the app to background when anyone hits back button
The actual solution is
#Override
public void onBackPressed() {
super.onBackPressed();
finishAffinity();
}
add this code in Login Activity. App closes when back button clicked in login page.