How to remove focus without setting focus to another control?

AndroidAndroid Layout

Android Problem Overview


I like my UIs to be intuitive; each screen should naturally and unobtrusively guide the user on to the next step in the app. Barring that, I strive to make things as confusing and confounding as possible.

Just kidding :-)

I've got three TableRows, each containing a read-only and non-focusable EditText control and then a button to its right. Each button starts the same activity but with a different argument. The user makes a selection there and the sub-activity finishes, populating the appropriate EditText with the user's selection.

It's the classic cascading values mechanism; each selection narrows the available options for the next selection, etc. Thus I'm disabling both controls on each of the next rows until the EditText on the current row contains a value.

I need to do one of two things, in this order of preference:

  1. When a button is clicked, immediately remove focus without setting focus to a different button
  2. Set focus to the first button when the activity starts

The problem manifests after the sub-activity returns; the button that was clicked retains focus.

Re: #1 above - There doesn't appear to be a removeFocus() method, or something similar

Re: #2 above - I can use requestFocus() to set focus to the button on the next row, and that works after the sub-activity returns, but for some reason it doesn't work in the parent activity's onCreate().

I need UI consistency in either direction--either no buttons have focus after the sub-activity finishes or each button receives focus depending on its place in the logic flow, including the very first (and only) active button prior to any selection.

Android Solutions


Solution 1 - Android

Using clearFocus() didn't seem to be working for me either as you found (saw in comments to another answer), but what worked for me in the end was adding:

<LinearLayout 
    android:id="@+id/my_layout" 
    android:focusable="true" 
    android:focusableInTouchMode="true" ...>

to my very top level Layout View (a linear layout). To remove focus from all Buttons/EditTexts etc, you can then just do

LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();

Requesting focus did nothing unless I set the view to be focusable.

Solution 2 - Android

Old question, but I came across it when I had a similar issue and thought I'd share what I ended up doing.

The view that gained focus was different each time so I used the very generic:

View current = getCurrentFocus();
if (current != null) current.clearFocus();

Solution 3 - Android

  1. You can use View.clearFocus().

  2. Use View.requestFocus() called from onResume().

Solution 4 - Android

android:descendantFocusability="beforeDescendants"

using the following in the activity with some layout options below seemed to work as desired.

 getWindow().getDecorView().findViewById(android.R.id.content).clearFocus();

in connection with the following parameters on the root view.

<?xml
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:descendantFocusability="beforeDescendants" />

https://developer.android.com/reference/android/view/ViewGroup#attr_android:descendantFocusability

Answer thanks to: https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text

About windowSoftInputMode

> There's yet another point of contention to be aware of. By default, > Android will automatically assign initial focus to the first EditText > or focusable control in your Activity. It naturally follows that the > InputMethod (typically the soft keyboard) will respond to the focus > event by showing itself. The windowSoftInputMode attribute in > AndroidManifest.xml, when set to stateAlwaysHidden, instructs the > keyboard to ignore this automatically-assigned initial focus. > > android:name=".MyActivity" > android:windowSoftInputMode="stateAlwaysHidden"/> > > great reference

Solution 5 - Android

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:id="@+id/ll_root_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">

LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();

I use this when already finished update profile info and remove all focus from EditText in my layout

====> Update: In parent layout content my EditText add line:

android:focusableInTouchMode="true"

Solution 6 - Android

What about just adding android:windowSoftInputMode="stateHidden" on your activity in the manifest.

Taken from a smart man commenting on this: https://stackoverflow.com/a/2059394/956975

Solution 7 - Android

I tried to disable and enable focusability for view and it worked for me (focus was reset):

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);

Solution 8 - Android

First of all, it will 100% work........

  1. Create onResume() method.
  2. Inside this onResume() find the view which is focusing again and again by findViewById().
  3. Inside this onResume() set requestFocus() to this view.
  4. Inside this onResume() set clearFocus to this view.
  5. Go in xml of same layout and find that top view which you want to be focused and set focusable true and focusableInTuch true.
  6. Inside this onResume() find the above top view by findViewById
  7. Inside this onResume() set requestFocus() to this view at the last.
  8. And now enjoy......

Solution 9 - Android

android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true"

Add them to your ViewGroup that includes your EditTextView. It works properly to my Constraint Layout. Hope this help

Solution 10 - Android

You could try turning off the main Activity's ability to save its state (thus making it forget what control had text and what had focus). You will need to have some other way of remembering what your EditText's have and repopulating them onResume(). Launch your sub-Activities with startActivityForResult() and create an onActivityResult() handler in your main Activity that will update the EditText's correctly. This way you can set the proper button you want focused onResume() at the same time you repopulate the EditText's by using a myButton.post(new Runnable(){ run() { myButton.requestFocus(); } });

The View.post() method is useful for setting focus initially because that runnable will be executed after the window is created and things settle down, allowing the focus mechanism to function properly by that time. Trying to set focus during onCreate/Start/Resume() usually has issues, I've found.

Please note this is pseudo-code and non-tested, but it's a possible direction you could try.

Solution 11 - Android

You do not need to clear focus, just add this code where you want to focus

 time_statusTV.setFocusable(true);
 time_statusTV.requestFocus();
 InputMethodManager imm = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
 imm.showSoftInput( time_statusTV, 0);

Solution 12 - Android

Try the following (calling clearAllEditTextFocuses();)

private final boolean clearAllEditTextFocuses() {
	View v = getCurrentFocus();
	if(v instanceof EditText) {
		final FocusedEditTextItems list = new FocusedEditTextItems();
		list.addAndClearFocus((EditText) v);

		//Focus von allen EditTexten entfernen
		boolean repeat = true;
		do {
			v = getCurrentFocus();
			if(v instanceof EditText) {
				if(list.containsView(v))
					repeat = false;
				else list.addAndClearFocus((EditText) v);
			} else repeat = false;
		} while(repeat);

		final boolean result = !(v instanceof EditText);
		//Focus wieder setzen
		list.reset();
		return result;
	} else return false;
}

private final static class FocusedEditTextItem {

	private final boolean focusable;

	private final boolean focusableInTouchMode;

	@NonNull
	private final EditText editText;

	private FocusedEditTextItem(final @NonNull EditText v) {
		editText = v;
		focusable = v.isFocusable();
		focusableInTouchMode = v.isFocusableInTouchMode();
	}

	private final void clearFocus() {
		if(focusable)
			editText.setFocusable(false);
		if(focusableInTouchMode)
			editText.setFocusableInTouchMode(false);
		editText.clearFocus();
	}

	private final void reset() {
		if(focusable)
			editText.setFocusable(true);
		if(focusableInTouchMode)
			editText.setFocusableInTouchMode(true);
	}

}

private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {

	private final void addAndClearFocus(final @NonNull EditText v) {
		final FocusedEditTextItem item = new FocusedEditTextItem(v);
		add(item);
		item.clearFocus();
	}

	private final boolean containsView(final @NonNull View v) {
		boolean result = false;
		for(FocusedEditTextItem item: this) {
			if(item.editText == v) {
				result = true;
				break;
			}
		}
		return result;
	}

	private final void reset() {
		for(FocusedEditTextItem item: this)
			item.reset();
	}

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionInteXXView Question on Stackoverflow
Solution 1 - AndroidactionshrimpView Answer on Stackoverflow
Solution 2 - AndroidwilllmaView Answer on Stackoverflow
Solution 3 - AndroidsiliconeagleView Answer on Stackoverflow
Solution 4 - AndroidCrandellWSView Answer on Stackoverflow
Solution 5 - AndroidHo LuongView Answer on Stackoverflow
Solution 6 - AndroidmarienkeView Answer on Stackoverflow
Solution 7 - AndroidSerhiyView Answer on Stackoverflow
Solution 8 - Androidvishambar pandeyView Answer on Stackoverflow
Solution 9 - AndroidTánh LeeView Answer on Stackoverflow
Solution 10 - AndroidUncle Code MonkeyView Answer on Stackoverflow
Solution 11 - AndroidFayyaz kharlView Answer on Stackoverflow
Solution 12 - Android5chw4hnView Answer on Stackoverflow