I had some issues using adjustPan in my app, as it is not working as it is supposed to do. Some other users also experienced this problem, so I think it's important to share this issue (Layout doesn't move up enough when clicking EditText).
Note: I am using Android Studio and I'm using an "Instant App", so the location of the files are going to be a bit different.
When I use adjustPan in my layout, my activity does not move up enough to the point where the EditText appears above the Soft Keyboard (See Image For Details). The same result still appears no matter if you use it in a Manifest file or a Java file.
Not only that, but the weirdest part is that Status Bar becomes transparent and the dark blue bar which is supposed to go behind the notification icons goes down a little bit (See Image For Details).
I have tried making several attempts of solving this issue, like using adjustResize and setOnTouchListener but both of these answers that I received didn't solve this issue.
I still can't figure out the cause of this issue, so any answers or comments regarding how to discover why this issue is happening is also fine.
Here is some of my code:
Manifest File:
<activity
android:name=".Input_Activity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
Java File:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.WindowManager;
public class Input_Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input__activity);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
}
XML File:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Input_Activity">
<EditText
android:layout_width="214dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:inputType="number|numberDecimal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.585"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.725" />
All feedback would be appreciated.
create an object like InputMethodManager methodManager at class level.
add these lines to your onCreate() method,
methodManager = (InputMethodManager) this.getSystemService(this.INPUT_METHOD_SERVICE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
and in your onClick() method, show keyboard like,
methodManager.toggleSoftInputFromWindow(
your_view_name.getApplicationWindowToken(),
InputMethodManager.SHOW_FORCED, 0);
If this word getApplicationWindowToken throws an error then replace it with getWindowToken
hope it helps.
android:windowSoftInputMode
Above attribute can be used to specify what happens with activity contents.
Below image can clear your doubts more
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.
adjustResize: The activity’s main window is always resized to make
room for the soft keyboard on screen.
I think there is no need add below code which you have added.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Also need to add following code in your onTouch event so that when soft keyboard appears it will go up. Example:
editText.setTransformationMethod(WordBreakUtil.getInstance());
editText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
return false;
}
});
I'm not sure about the answer. but try replacing
<activity
android:name=".Input_Activity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
with
<activity
android:name=".Input_Activity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
in your android manifest.
Read here
Hope this helps!
Related
I want to create a dynamic login screen that includes a decorative branding image when the screen is sufficiently tall but excludes the image on short screens. When the keyboard appears, it's likely the image will need to be removed. When the keyboard is hidden, the image can come back.
With a web page, I'd just use CSS media queries for the device height, show or hide the image appropriately, and it would all work nicely. I don't think anything that simple and clean is possible for an Android view, is it? So I figure I need to know the height of the window when the activity is created and create the view appropriately.
In the manifest, I've set my main activity to adjustResize when the keyboard appears. When the keyboard appears, my view does resize but my activity is surprisingly not recreated. When the screen is rotated, the activity is recreated.
The documentation says the view will be recreated when the keyboard availability changes. The first paragraph from https://developer.android.com/guide/topics/resources/runtime-changes
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and when the user enables multi-window mode). When such a change occurs, Android restarts the running Activity ( onDestroy() is called, followed by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.
My questions are
What's the best way to handle my design goal?
Why is my activity not recreated when the keyboard appears?
Below are the relevant parts of my test app. There is no image in this as I didn't even get that far before running into what seems like behavior contradicting the documentation.
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Log.d("MainActivity", "onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/intro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#color/colorAccent" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/intro"
android:singleLine="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Bottom"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#color/colorAccent" />
</android.support.constraint.ConstraintLayout>
The activity isn't recreated when the keyboard appears because that isn't how Android works. Its not supposed to be. (Although if you have an old fashioned device with a slide out physical keyboard it will be recreated when you slide it out, because its treated as a hardware configuration change). Keyboards being shown/hidden is done without recreation. Which is a good thing, that many recreate events would be expensive given how many people just shove a ton of logic into onCreate.
How to do what you want- you can't. There is no API to detect when the keyboard is opened. There are commonly used hacks that attempt to discover it, but they're all flawed (they can have problems with split screen mode, picture in picture mode, multiple screens, and keyboards which are too small, because they all work based on guessing based on height changes).
The method OnFocusChangeListener() will detect whenever a View gains or loses focus. EditText makes the keyboard show up whenever it gains focus. Therefore, you should attach a OnFocusChangeListener() to those EditText that you want:
EditText myET = (EditText)findViewById(R.id.myET);
myET.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
//Hide image
} else {
//Reveal image
}
}
});
Moreover, to hide and reveal the image you should use the property called visibility.
The methods are:
myImageView.setVisibility(View.VISIBLE); //This will show the Image
myImageView.setVisibility(View.INVISIBLE); //This will make the Image invisible
myImageView.setVisibility(View.GONE); //This will make the Image invisible, and also it will collapse the layout, occupying no space at all.
Don't try using INVISIBLE and GONE simultaneously, since that could cause some trouble. In your case, from what I understand you might want to use GONE and VISIBLE.
The only problem with this approach is that if you have multiple EditText, you would have to set up many times the same code. To solve that, please refer to the following link:
EditText setOnFocusChangeListener on all EditTexts
I've been searching for an answer and I came across this:
https://developer.android.com/training/keyboard-input/visibility#java
It says android DOES do what you want.
I just tried it, add 1 line, ONE LINE!, to your manifest and it works.
Oh wait... you want the brand to disappear... hmmm well with this it wouldn't have to?
DOH! You already knew about that.....
"What you want to do you can't"...
I don't know how to do it, but I disagree that it can't be done. I have the PayPal app and when the keyboard appears the login button and the rest of the login screen resize so that the login button isn't covered by the keyboard. How they're doing it, I don't know, but obviously somehow the app knows the keyboard appears and adjusts accordingly.
I've been searching for an answer and I came across this:
https://developer.android.com/training/keyboard-input/visibility#java
It says android DOES resize the screen when then soft keyboard appears/disappears.
I just tried it, add 1 line, ONE LINE!, to your manifest and it works.
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.
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);
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"/>
I have a screen where the first field is an EditText, and it gains the focus at startup, also popups the numeric input type, which is very annoying
How can I make sure that when the activity is started the focus is not gained, and/or the input panel is not raised?
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editTextField.getWindowToken(), 0);
or
set activity property in manifest file as below in the application tag
android:windowSoftInputMode="stateHidden"
go to your application manifest file, and write this line for that activity you want to disable auto keyboard pop-up.
android:windowSoftInputMode="stateHidden"
To programatically not have the keyboard displayed, but the default widget still recieve focus call:
getWindow().setSoftInputMode(WindowManager.
LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
in onResume()
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
call the above method inside onCreate().It prevent softKeyboard to show unless user select EditText by tapping or clicking.
or simply add android:windowSoftInputMode="stateHidden" in Activity tag in Manifest.xml
This is usually a mess. The first thing I try is try to steal the focus with another view via . You also have to have the focusable and focusableInTouchMode.
<TextView
...
android:focusable="true"
android:focusableInTouchMode="true">
<requestFocus/>
</TextView>
Have another view grab focus. By default, the first focusable View will get focus when a layout is inflated. You can request focus on a different View via XML:
<TextView
android:layout_width="wrap_parent"
android:layout_height="wrap_content"
android:text="Some other view">
<requestFocus />
</TextView>
This works for any View.
If you want to do it programmatically, you can use view.requestFocus().
Adding android:windowSoftInputMode="stateHidden" to your Activity in manifest only hides the keyboard when you are launching the activity, or as Google says
When the user affirmatively navigates forward to the activity, rather
than backs into it because of leaving another activity
To hide the keyboard also when user presses the back button and moves back to your activity from some other activity, use android:windowSoftInputMode="stateAlwaysHidden"
if(getWindow().getAttributes().softInputMode==WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED)
{
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
have not tried this nor am i near my programming computer, but I would suspect programmatically sending focus to the parent view or something of that nature could do the trick - thats more likely a workaround than a solution, but again not able to test it just a thought