I have an Activity
in Android, with two elements:
EditText
ListView
When my Activity
starts, the EditText
immediately has input focus (flashing cursor). I don't want any control to have input focus at startup. I tried:
EditText.setSelected(false);
EditText.setFocusable(false);
No luck. How can I convince the EditText
to not select itself when the Activity
starts?
This question is related to
android
listview
android-edittext
focus
remove<requestFocus />
from your edit text in xml file
<EditText
android:id="@+id/emailField"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress">
//`<requestFocus />` /* <-- remove this tags */
</EditText>`
I had an issue like this and it was due to my selector. The first state was focus even thogh my view was disabled it took the focus state since it was the first one that matched and used it. you can set the first state to disabled like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/text_field_disabled" android:state_enabled="false"/>
<item android:drawable="@drawable/text_field_focused" android:state_focused="true"/>
<item android:drawable="@drawable/text_field_normal"/>
Add following in onCreate
method:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
It can be achieved by inheriting EditText
and overriding onTouchEvent
.
class NonFocusableEditText: EditText {
constructor(context: Context): super(context)
constructor(context: Context, attrs: AttributeSet?): super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
override fun onTouchEvent(event: MotionEvent?): Boolean {
return if (isFocusable) super.onTouchEvent(event) else false
}
}
Then you can use it in the layouts like normal EditText
:
<com.yourpackage.NonFocusableEditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/your_hint"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions" />
I clear all focus with submit button
XML file:
<LinearLayout
...
android:id="@+id/linear_layout"
android:focusableInTouchMode="true"> // 1. make this focusableInTouchMode...
</LinearLayout>
JAVA file:
private LinearLayout mLinearLayout; // 2. parent layout element
private Button mButton;
mLinearLayout = findViewById(R.id.linear_layout);
mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLinearLayout.requestFocus(); // 3. request focus
}
});
I hope this helps you :)
<EditText
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="@+id/etComments"
android:hint="Comments.."
android:textSize="14dp"
android:focusable="false"
android:textStyle="italic"/>
try
edit.setInputType(InputType.TYPE_NULL);
edit.setEnabled(false);
The easiest way is to add android:windowSoftInputMode="stateAlwaysHidden"
in the activity tag of the Manifest.xml file
Is the actual problem that you just don't want it to have focus at all? Or you don't want it to show the virtual keyboard as a result of focusing the EditText
? I don't really see an issue with the EditText
having focus on start, but it's definitely a problem to have the softInput window open when the user did not explicitly request to focus on the EditText
(and open the keyboard as a result).
If it's the problem of the virtual keyboard, see the AndroidManifest.xml
<activity> element documentation.
android:windowSoftInputMode="stateHidden"
- always hide it when entering the activity.
or android:windowSoftInputMode="stateUnchanged"
- don't change it (e.g. don't show it if it isn't already shown, but if it was open when entering the activity, leave it open).
Try this before your first editable field:
<TextView
android:id="@+id/dummyfocus"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/foo"
/>
----
findViewById(R.id.dummyfocus).setFocusableInTouchMode(true);
findViewById(R.id.dummyfocus).requestFocus();
Being that I don't like to pollute the XML with something that is related to functionality, I created this method that "transparently" steals the focus from the first focusable view and then makes sure to remove itself when necessary!
public static View preventInitialFocus(final Activity activity)
{
final ViewGroup content = (ViewGroup)activity.findViewById(android.R.id.content);
final View root = content.getChildAt(0);
if (root == null) return null;
final View focusDummy = new View(activity);
final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
{
@Override
public void onFocusChange(View view, boolean b)
{
view.setOnFocusChangeListener(null);
content.removeView(focusDummy);
}
};
focusDummy.setFocusable(true);
focusDummy.setFocusableInTouchMode(true);
content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
if (root instanceof ViewGroup)
{
final ViewGroup _root = (ViewGroup)root;
for (int i = 1, children = _root.getChildCount(); i < children; i++)
{
final View child = _root.getChildAt(i);
if (child.isFocusable() || child.isFocusableInTouchMode())
{
child.setOnFocusChangeListener(onFocusChangeListener);
break;
}
}
}
else if (root.isFocusable() || root.isFocusableInTouchMode())
root.setOnFocusChangeListener(onFocusChangeListener);
return focusDummy;
}
This is the perfect and most easiest solution.I always use this in my app.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
When your activity is opened, keyboard gets visible automatically which causes focusing of EditText. You can disable keyboard by writing the following line in your activity tag in manifest.xml file.
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
Simple solution:
In AndroidManifest
in Activity
tag use
android:windowSoftInputMode="stateAlwaysHidden"
Yeah I did the same thing - create a 'dummy' linear layout which gets initial focus. Furthermore, I set the 'next' focus IDs so the user can't focus it any more after scrolling once:
<LinearLayout 'dummy'>
<EditText et>
dummy.setNextFocusDownId(et.getId());
dummy.setNextFocusUpId(et.getId());
et.setNextFocusUpId(et.getId());
a lot of work just to get rid of focus on a view..
Thanks
The only solution I've found is:
android:focusable="true"
and android:focusableInTouchMode="true"
And the EditText
won't get the focus after starting the activity
Late but simplest answer, just add this in parent layout of the XML.
android:focusable="true"
android:focusableInTouchMode="true"
Upvote if it helped you ! Happy Coding :)
I use the following code to stop an EditText from stealing the focus when my button is pressed.
addButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
View focused = internalWrapper.getFocusedChild();
focused.setVisibility(GONE);
v.requestFocus();
addPanel();
focused.setVisibility(VISIBLE);
}
});
Basicly, hide the edit text and then show it again. This works for me as the EditText is not in view so it doesn't matter whether it is showing.
You could try hiding and showing it in succession to see if that helps it lose focus.
Disable it in onCreate()
final KeyListener edtTxtMessageKeyListener = edtTxtMessage.getKeyListener();
edtTxtMessage.setCursorVisible(false);
edtTxtMessage.setKeyListener(null);
And finally enable it in onClick() of EditText
edtTxtMessage.setCursorVisible(true);
edtTxtMessage.setKeyListener(edtTxtMessageKeyListener);
But the problem is with we have to click twise to bring OnScreenKeyboard for very first time.
@Workaround
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
Try this also in onClick() :)
You have edit text and list. In OnStart/On Create, you should set focus on list view: Listview.requestfocus()
The simplest thing I did is to set focus on another view in onCreate:
myView.setFocusableInTouchMode(true);
myView.requestFocus();
This stopped the soft keyboard coming up and there was no cursor flashing in the EditText.
EditText
within a ListView
does not work properly. It's better to use TableLayout
with automatically generated rows when you are using EditText
.
If you want to hide the keyboard at the start of the activity. Then mention
android:windowSoftInputMode="stateHidden"
To that activity in the manifest file. Problem gets solved.
Cheers.
For me, what worked on all devices is this:
<!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->
<View
android:layout_width="0px"
android:layout_height="0px"
android:focusable="true"
android:focusableInTouchMode="true" />
Just put this as a view before the problematic focused view, and that's it.
The following worked for me in Manifest
. Write ,
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Easiest way to hide keyboard is using setSoftInputMode
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
or you can use InputMethodManager and hide keyboard like this.
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
<TextView
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
style="@android:style/Widget.EditText"/>
I needed to clear focus from all fields programmatically. I just added the following two statements to my main layout definition.
myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);
That's it. Fixed my problem instantly. Thanks, Silver, for pointing me in the right direction.
At onCreate
of your Activity, just add use clearFocus()
on your EditText element.
For example,
edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();
And if you want to divert the focus to another element, use requestFocus()
on that.
For example,
button = (Button) findViewById(R.id.button);
button.requestFocus();
A simpler solution exists. Set these attributes in your parent layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true" >
And now, when the activity starts this main layout will get focus by default.
Also, we can remove focus from child views at runtime (e.g., after finishing child editing) by giving the focus to the main layout again, like this:
findViewById(R.id.mainLayout).requestFocus();
Good comment from Guillaume Perrot:
android:descendantFocusability="beforeDescendants"
seems to be the default (integer value is 0). It works just by addingandroid:focusableInTouchMode="true"
.
Really, we can see that the beforeDescendants
set as default in the ViewGroup.initViewGroup()
method (Android 2.2.2). But not equal to 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;
Thanks to Guillaume.
You can specify focus to some other widget by using request focus and use the keyboard hiding code as well.
Try clearFocus() instead of setSelected(false)
. Every view in Android has both focusability and selectability, and I think that you want to just clear the focus.
/**
* set focus to top level window
* disposes descendant focus
* disposes softInput
* */
public static void topLevelFocus(Context context){
if(Activity.class.isAssignableFrom(context.getClass())){
ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView();
if(tlView!=null){
tlView.setFocusable(true);
tlView.setFocusableInTouchMode(true);
tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
}
}
Simply add android:focusableInTouchMode="true"
in parent layout of EditText and you will get rid of this awkward behavior.
Write this code inside Manifest
file in the Activity
where you do not want to open the keyboard.
android:windowSoftInputMode="stateHidden"
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.projectt"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="24" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".Splash"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Login"
**android:windowSoftInputMode="stateHidden"**
android:label="@string/app_name" >
</activity>
</application>
</manifest>
Add android:windowSoftInputMode="stateAlwaysHidden"
in the activity tag of the Manifest.xml
file.
Make sure to remove the line "<requestFocus />"
from the EditText
tag in xml.
<EditText
android:id="@+id/input"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<requestFocus /> <!-- remove this line -->
</EditText>
You can just set "focusable" and "focusable in touch mode" to value true on the first TextView
of the layout
. In this way when the activity starts the TextView
will be focused but , due to its nature, you will see nothing focused on the screen and ,of course, there will be no keyboard displayed...
None of this solutions worked for me. The way I fix the autofocus was:
<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
<intent-filter >
</intent-filter>
</activity>
Write this line in your Parent Layout...
android:focusableInTouchMode="true"
add below line in Manifest file where you have mentioned your activity
android:windowSoftInputMode="stateAlwaysHidden"
Simple and reliable solution , just override this method :
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
View v = getCurrentFocus();
if (v != null &&
(ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) &&
v instanceof EditText &&
!v.getClass().getName().startsWith("android.webkit.")) {
int scrcoords[] = new int[2];
v.getLocationOnScreen(scrcoords);
float x = ev.getRawX() + v.getLeft() - scrcoords[0];
float y = ev.getRawY() + v.getTop() - scrcoords[1];
if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())
hideKeyboard(this);
}
return super.dispatchTouchEvent(ev);
}
public static void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null && activity.getWindow().getDecorView() != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
}
}
View current = getCurrentFocus();
if (current != null)
current.clearFocus();
The following will stop edittext from taking focus when created, but grab it when you touch them.
<EditText
android:id="@+id/et_bonus_custom"
android:focusable="false" />
So you set focusable to false in the xml, but the key is in the java, which you add the following listener:
etBonus.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
v.setFocusable(true);
v.setFocusableInTouchMode(true);
return false;
}
});
Because you are returning false, i.e. not consuming the event, the focusing behavior will proceed like normal.
I had tried several answers individually but the focus is still at the EditText. I only managed to solve it by using two of the below solution together.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true" >
( Reference from Silver https://stackoverflow.com/a/8639921/15695 )
and remove
<requestFocus />
at EditText
( Reference from floydaddict https://stackoverflow.com/a/9681809 )
The problem seems to come from a property that I can only see in the XML form
of the layout.
Make sure to remove this line at the end of the declaration within the EditText
XML tags:
<requestFocus />
That should give something like that :
<EditText
android:id="@+id/emailField"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress">
//<requestFocus /> /* <-- without this line */
</EditText>
You can achieve this by creating a dummy EditText
with layout width and height set to 0dp
, and request focus to that view.
Add the following code snippet in your xml layout:
<EditText
android:id="@+id/editText0"
android:layout_width="0dp"
android:layout_height="0dp"
android:hint="@string/dummy"
android:ems="10"
>
<requestFocus />
</EditText>
Lots of working answers already provided but I think we can do a little better by using the below simple method
//set focus to input field
private fun focusHere() {
findViewById<TextView>(R.id.input).requestFocus()
}
in place of input in R.id.input use any other view id to set focus to that view.
Late, but maybe helpful. Create a dummy EditText at the top of your layout then call myDummyEditText.requestFocus()
in onCreate()
<EditText android:id="@+id/dummyEditTextFocus"
android:layout_width="0px"
android:layout_height="0px" />
That seems to behave as I expect. No need to handle configuration changes, etc. I needed this for an Activity with a lengthy TextView (instructions).
If you have another view on your activity like a ListView
, you can also do:
ListView.requestFocus();
in your onResume()
to grab focus from the editText
.
I know this question has been answered but just providing an alternative solution that worked for me :)
Do this and get your job done!
android:focusable="true"
android:focusableInTouchMode="true"
using the information provided by other posters, I used the following solution:
in the layout XML
<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
android:id="@+id/linearLayout_focus"
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<!-- AUTOCOMPLETE -->
<AutoCompleteTextView
android:id="@+id/autocomplete"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:inputType="textNoSuggestions|textVisiblePassword"/>
in onCreate()
private AutoCompleteTextView mAutoCompleteTextView;
private LinearLayout mLinearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
//get references to UI components
mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);
}
and finally, in onResume()
@Override
protected void onResume() {
super.onResume();
//do not give the editbox focus automatically when activity starts
mAutoCompleteTextView.clearFocus();
mLinearLayout.requestFocus();
}
Source: Stackoverflow.com