Stop EditText from bringing up the keyboard on Activity start? - android

I have an Edit Text in one of my App layouts, and I want this EditText to only open the keyboard (I believe this is called being focused on?) when it is actually touched.
As of now, the keyboard opens with the EditText whenever the app opens, which isn't what I want.
I have tried many different XML tags to fix this:
android:focusable="false" <--- Prevents keyboard from opening at all.
android:focusable="true"
android:focusableInTouchMode = "true" <--- These tags give me the same result as no tags (keybaord will open on activity start)
android:focusedByDefault = "true" <--- Only available in API >= 23
What I am asking is, why is it so hard to disable default focus on an EditText? Surely I am missing an easy way to do this.
EDIT: Adding this line to my AndroidManifest fixed the issue:
android:windowSoftInputMode="stateHidden"
However, I don't like this solution. It seems like since this is in the Manifest, it will affect more UI elements than the single EditText I need to change.

Alternatively you can set the focus to the root layout element:
android:focusable="true"
android:focusableInTouchMode="true"
Example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:inputType="text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

Use android:windowSoftInputMode="stateHidden"
If you dig deep into the Theme you are using for your Activity, you will find that the default value of windowSoftInputMode is stateUnspecified|adjustPan. And from the documentation:
stateUnspecified: Not specified, use what the system thinks is best. This is the default.
So depending on the the android device you run, your results will vary. I tried reproducing your case in API-26 emulator and the keyboard doesn't show up.You can use stateHidden to ensure that when an activity starts, the soft keyboard doesn't show up when the EditText gets focused on itself.
The other way to solve this is to requestFocus to some other element in the UI, making sure the EditText is not the first UI element to get focused. In my experience this is kind of a hack and it messes up the accessibility. The safest and clean way to accomplish is actually to use stateHidden.
stateHidden: Make the soft input area hidden when normally appropriate (when the user is navigating forward to your window).
Note that this will not affect any other UI elements. You can use adjustPan also to this, based on the screen background.

Related

How to force the soft input to overlap bottom-anchored View?

TL;DR: soft keyboard should overlap a bottom-anchored view instead of pushing it up. Gitlab link for an mcve.
Summary:
I have an AppCompatDialogFragment (androidx) which appears fullscreen on phones and has fixed dimensions on tablets (using dialog?.window?.setLayout(width, height) in case this matters). The dialog's layout has some content placed in a ScrollView and a button-like layout anchored at the bottom (complete XML structure see below).
Side note: the superclass of the AppCompatDialogFragment in question calls setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)on its Window.
The problem:
When the soft keyboard appears as a result of some text input receiving focus, it pushes the complete layout up, including the bottom-anchored view that I want overlapped by the soft keyboard. For some reason, the issue only affects phones, on tablets the soft keyboard correctly overlaps everything including the bottom-anchored view without any additional adjustments or flags.
What I have tried (without any success):
setting android:windowSoftInputMode="adjustNothing" (tried other flags "just in case" as well) for the Activity in question, also tried to apply them in code
setting android:isScrollContainer="false" on the ScrollView and its parent
combinations of the above
looking for similar questions like this one and confirming the proposed solutions didn't work
Here's the layout in question (note: I omitted many unrelated attributes to keep the snippet reasonably sized; everything is positioned vertically matching the elements' order. The <include> elements contain the text inputs):
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/bottom_layout"
app:layout_constraintTop_toBottomOf="#id/toolbar"
android:isScrollContainer="false"
android:scrollbarStyle="outsideOverlay">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="#layout/some_layout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include
layout="#layout/some_layout_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<!-- I want this one to be overlapped by the soft input, but it's just pushed up -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/bottom_layout"
app:layout_constraintBottom_toBottomOf="parent">
<View
android:layout_width="match_parent"
android:layout_height="#dimen/divider"
android:background="#color/dark_grey" />
<TextView
android:layout_width="match_parent"
android:layout_height="#dimen/some_dimen"
android:foreground="?attr/selectableItemBackground"
android:text="#string/text" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
The question: how do I force the soft keyboard to overlap the layout anchored at the bottom on all devices?
Please comment if you need any additional details.
EDIT: here's a minimal demo app that reproduces the issue: https://gitlab.com/Droidman/soft-keyboard-issue-demo
Try adding the following line to onCreateView() of DemoDialog:
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
It is important to apply this change to the window of the dialog and not to the window of the activity.
With this in place, this is what I see on an Nexus 6 emulator running API 29 using your MCVE:
You may need to work with the placement a little, but this should help.
Let's look under the hood a little. For a phone and a tablet, the soft input mode is zero in onCreateView(). This value corresponds to SOFT_INPUT_ADJUST_UNSPECIFIED. The documentation for SOFT_INPUT_ADJUST_PAN explains what happens when the soft input mode is unspecified (emphasis is mine.)
Adjustment option for softInputMode : set to have a window pan when an input method is shown, so it doesn't need to deal with resizing but just panned by the framework to ensure the current input focus is visible. This can not be combined with SOFT_INPUT_ADJUST_RESIZE ; if neither of these are set, then the system will try to pick one or the other depending on the contents of the window.
Looking at the value of the soft input mode in onStart() (dialog?.window?.attributes?.softInputMode) shows the value selected by the system for the phone is SOFT_INPUT_ADJUST_RESIZE) and the value selected for the tablet is SOFT_INPUT_ADJUST_PAN. This explains the difference that is seen between phones and tablets.
So, always setting the soft input mode to SOFT_INPUT_ADJUST_PAN looks like the best solution although SOFT_INPUT_ADJUST_NOTHING also works and may be preferable for certain layouts.
Add this to your class inside the tags in the AndroidManifest in your Class:
android:windowSoftInputMode="stateHidden|adjustResize"

EditText doesn't start automatically

In my app, I have an EditText. How do I make it doesn't start automatically? Like: once they open the activity it automatically sets the mouse to the EditText and the keyboard gets opened so they type…
Is there anyway I can make it open (the keyboard shows and the user can type) when they clicks on it?
Ok, so from your question i figure out that your EditText is getting focus while starting the activity. You can disable the focus using following command to suppress the keyboard.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Visit this Close/hide the Android Soft Keyboard
the answer by Lucifer must work. But when i got the same problem, that solution did't work, and someone suggested me this.
add a fake layout as the first element in you parent layout and make it focusable.
Like this:
<ParentLayout
.....
......>
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/transparent"
android:focusable="true"
android:focusableInTouchMode="true" >
</LinearLayout>
......
......
......
</ParentLayout>
This definitely works, but the best solution is:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

android adjustresize adjustpan famous issue

I'm not looking for code, either I won't post any, just an explanation, because I'm kind of lost.
There is this main issue about the resizing when softkeyboard appear.
In my case
I have a listView feeded with 2 editText and many textView with database content using a custom cursorAdapter.
1) AdjustPan
It's pretty simple. When I use the adjustPan property, everything works quite good, except the fact that when I press an editText in my listView and if the listview is bigger than the screensize, I can't scroll. This is actually the normal behaviour and I can understand it.
2) AdjustResize
Here I can scroll as much as I wish.
This property is the one I want to use. But I'm facing 2 issues :
When I press on one of the two editText, I just can't write in. Impossible, even thought it has the focus. I'm forcing the softkeyboard to appear, I try to type some letters in (remember that this editText is focused) but nothing happens.
Again, when I press one of the two editText, it just reorganize (apparently randomly) listview's items. Even thought it's working perfectly with adjustPan, with adjustResize, it's messing with items of the listView.
Any information about one of the 2 issues would be helpful. You can even ask for code, but one more time, I'm just looking for a general explanation that could help. Thanks.
Here this mention issue is same facing me in my app and here some change in my code is this working fine in my app. please try this...
<activity android:name="com.MainActivity"
android:configChanges="orientation|screenSize"/>
<ListView
android:id="#+id/fields_list_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:descendantFocusability="afterDescendants"
android:focusableInTouchMode="true"
android:focusable="true"
/>
<EditText
android:id="#+id/input_edit_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:cursorVisible="true"
android:gravity="top"
android:inputType="none"
android:textColor="#color/black"/>

adjustPan not preventing keyboard from covering EditText

I'm trying to create a pretty basic chat screen with a ListView displaying the text and an EditText at the bottom and a "Send" button to the right of the EditText. Everything is functional, but when I click the EditText, the virtual keyboard covers it. The screen pans up a little but not enough to become visible above the keyboard. I've got the "adjustPan" tag in my manifest and have also tried the "adjustResize" tag to no avail. I'm guessing it has something to do with the way my layout is set up, but I honestly have no clue. Please help!
Current Layout...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="#+id/android:list"
android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1"
android:stackFromBottom="true">
</ListView>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText android:id="#+id/sendMessageBox"
android:focusable="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="vertical"
android:maxLines="4"
android:text=""
android:inputType="textShortMessage|textAutoCorrect|textCapSentences|textMultiLine"
android:maxLength="1000"
android:hint="Type your message..."
android:imeOptions="actionSend"/>
<Button android:id="#+id/sendMessageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Send"/>
</LinearLayout>
After doing a lot of searching apparently it's what I'm calling a bug. If you use the fullscreen tag (to remove the status bar from the activity) you can't use "adjustResize" without wrapping the activity in a ScrollView. Unfortunately for me I'm using a ListView which would create yet another problem. I'm sick of messing with it and will probably just abandon the fullscreen on that activity.
In your manifest file, you need to set the appropriate android:windowSoftInputMode property. This attribute is valid since API 3.
<activity
...
android:windowSoftInputMode="adjustPan" >
</activity>
Options are: http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft
stateUnspecified The state of the soft keyboard (whether it is hidden or visible) is not specified. The system will choose an
appropriate state or rely on the setting in the theme. This is the
default setting for the behavior of the soft keyboard.
stateUnchanged The soft keyboard is kept in whatever state it was last in, whether visible or hidden, when the activity comes to the
fore.
"stateHidden" The soft keyboard is hidden when the user chooses the activity — that is, when the user affirmatively navigates forward
to the activity, rather than backs into it because of leaving another
activity.
stateAlwaysHidden The soft keyboard is always hidden when the activity's main window has input focus.
stateVisible The soft keyboard is visible when that's normally appropriate (when the user is navigating forward to the activity's
main window).
stateAlwaysVisible The soft keyboard is made visible when the user chooses the activity — that is, when the user affirmatively
navigates forward to the activity, rather than backs into it because
of leaving another activity.
adjustUnspecified It is unspecified whether the activity's main window resizes to make room for the soft keyboard, or whether the
contents of the window pan to make the current focus visible
on-screen. The system will automatically select one of these modes
depending on whether the content of the window has any layout views
that can scroll their contents. If there is such a view, the window
will be resized, on the assumption that scrolling can make all of the
window's contents visible within a smaller area. This is the default
setting for the behavior of the main window.
adjustResize The activity's main window is always resized to make room for the soft keyboard on screen.
adjustPan The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are
automatically panned so that the current focus is never obscured by
the keyboard and users can always see what they are typing. This is
generally less desirable than resizing, because the user may need to
close the soft keyboard to get at and interact with obscured parts of
the window.
if you set android:windowSoftInputMode="adjustResize" for an activity in the manifest, then a ScrollView (or other collapsable ViewGroups) will shrink to accommodate the soft keyboard. But, if you set android:windowFullscreen="true" in the activity’s theme, then the ScrollView won’t shrink because it’s forced to fill the whole screen. However, setting android:fitsSystemWindows="false" in your theme also causes adjustResize not to work
I had this in my AndroidManifest. It caused the adjustPan to stop working correctly. I removed the block below and everything works fine again.
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="false"
android:anyDensity="false" />
Here is one workaround I have found. Open the problematic editText and hit the RETURN key. Notice it shifts the editText closer to the position you're shooting for.
So although hacky, you can essentially please a newline at the top of the edittext.
This also seems to work using a newline at the bottom but you'd have to use a delay to not add the newline until AFTER the soft keyboard has animated into position.
Note I only have this problem on certain phones (DroidX).
if (android.os.Build.MODEL.equals("DROIDX")) {
inputEt.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
String text = inputEt.getText().toString();
text = "\n\n" + text.trim();
inputEt.setText(text);
inputEt.setSelection(text.length());
}
});
}
Try adding android:windowSoftInputMode="adjustResize|stateVisible|stateAlwaysHidden" in your manifest.
You can try the following settings:
<supports-screens
android:anyDensity="true"/>

Android - customized keyboard key and action

If you own Android phone you are no doubt have noticed how in the certain apps the keyboard layout can change from the standard issue to digits-only or to have .com or .net special buttons based on the text field input type (e.g. phone number). So I have 2 questions:
how to trigger this customization? I suspect it has to do with EditText format
Can this be taken even further if I want to add some custom buttons to inject a specific pattern? Say I would have an AND button which when pressed will add all uppercase " AND " surrounded by spaces to the text field. Can this be done?
What I'm not asking is how to capture some key combination in onKeyPress event and then populate text field with a pattern - I pretty much know how to do that already.
It is controlled by the android:inputType XML attribute (or the setInputType() method).
For info on the available options see the pages for the XML attribute or the object's method.
As an example, the following XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:text="example text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone" />
</LinearLayout>
will give you this layout:
whereas changing the inputType to textEmailAddress will give you this:
You can customize the "action" button as explained here, but I don't believe there's any way to do full customization of keyboards at this time, but I could be wrong.
The thing that concerns me is that "inputType" is listed as a deprecated property, meaning it may work for a while, but - eventually - Android will stop supporting it. Is there another alternative?
UPDATED: My bad - I'm confusing with inputMethod.

Categories

Resources