Android remove focus from all Views - android

This is a fairly simple question but I can't believe all answers I found were not working.
I have a layout with two EditText and the bottom of the window is just some remaining blank space. I'd like each EditText to loose focus when the user is clicking in the blank part of the window. So my guess is that I have to put something in the OnTouchListener of the root View:
rootView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Put something here
}
});
I have tried several things:
Requesting focus from the layout View as suggested somewhere was in fact giving focus to one of the EditTexts.
I also tried setting setFocusable for both EditTexts to false but I was unable to put them back to true afterwards.
I also tried the simple rootView.clearFocus(), but it was also giving back the focus to one EditText.
EDIT: My EditText boxes are multilines so I can't use a 'Done' keyboard button since I need the return one to be present.

<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"

In Kotlin:
view?.clearFocus()
In Java:
getView().clearFocus();

Related

how can full clear focus in editText , just like press button DONE on softkeyboard

I specify different backgrounds when edit text focus changed , but clearFocus() seem like no effect , because the background do not change to the right state .
Firstly, we can use cleareFocus method to remove the focus.
editTextView.clearFocus()
But when this method is called, as source code comment says:
When not in touch-mode, the framework will try to give focus to the first focusable View from the top after focus is cleared. Hence, if this
View is the first from the top that can take focus, then all callbacks
related to clearing focus will be invoked after which the framework will
give focus to this view.
so after you call it, the first element will stay get the focus. so we should set the touch-mode true in parent layout.
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<EditText android:id="#+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Create one more EditText(edit_hidden) and set visibility GONE or INVISIBLE
When you want to clear Focus from your EditText(edit_your) then use this Code
edit_your.clearFocus();
edit_hidden.requestFocus();
Using Action Done Event
edit_your.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_DONE){
edit_your.clearFocus();
edit_hidden.requestFocus();
}
return false;
}
});

clearFocus() on empty editText is not working in Android

I tried to remove focus from empty editText but it isn't working correctly.
I called clearFocus() on edittext ,and then I placed break point at my onFocusChanged() function call.
Here is what happened:
onFocusChanged() called 4 times with the focused parameters values false,true,false,true.
What I thought was that onFocusChanged() must be called only once (with focused = false)
Sorry for my bad English. Any help would be appreciated.
Thanks
In xml, make parent layout
android:focusable="true"
android:focusableInTouchMode="true"
and then call clearFocus on edit text and then call parent request focus
mFragmentBase.editText.clearFocus();
mFragmentBase.parentLayout.requestFocus();
This is happening because your EditText is the first focusable view.
From the docs,
Note: When a View clears focus the framework is trying to give focus
to the first focusable View from the top. Hence, if this View is the
first from the top that can take focus, then all callbacks related to
clearing focus will be invoked after which the framework will give
focus to this view.
You can try setting a dummy focusable view above the EditText to clear the focus from it.
Instead of clearing the focus from EditText create an empty view at the top of the layout
<LinearLayout
android:id="#+id/focusableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
android:focusableInTouchMode="true"/>
and declare a utility function to hide the keyboard like this
fun hideKeyboard(activity: Activity) {
val inputMethodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(activity.currentFocus?.windowToken, 0)
}
Finally when you need to clear focus just call
focusableLayout.requestFocus()
hideKeyboard(currentActivity)

Android ListView with EditText focus issues [duplicate]

I've spent about 6 hours on this so far, and been hitting nothing but roadblocks. The general premise is that there is some row in a ListView (whether it's generated by the adapter, or added as a header view) that contains an EditText widget and a Button. All I want to do is be able to use the jogball/arrows, to navigate the selector to individual items like normal, but when I get to a particular row -- even if I have to explicitly identify the row -- that has a focusable child, I want that child to take focus instead of indicating the position with the selector.
I've tried many possibilities, and have so far had no luck.
layout:
<ListView
android:id="#android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Header view:
EditText view = new EditText(this);
listView.addHeaderView(view, null, true);
Assuming there are other items in the adapter, using the arrow keys will move the selection up/down in the list, as expected; but when getting to the header row, it is also displayed with the selector, and no way to focus into the EditText using the jogball. Note: tapping on the EditText will focus it at that point, however that relies on a touchscreen, which should not be a requirement.
ListView apparently has two modes in this regard:
1. setItemsCanFocus(true): selector is never displayed, but the EditText can get focus when using the arrows. Focus search algorithm is hard to predict, and no visual feedback (on any rows: having focusable children or not) on which item is selected, both of which can give the user an unexpected experience.
2. setItemsCanFocus(false): selector is always drawn in non-touch-mode, and EditText can never get focus -- even if you tap on it.
To make matters worse, calling editTextView.requestFocus() returns true, but in fact does not give the EditText focus.
What I'm envisioning is basically a hybrid of 1 & 2, where rather than the list setting if all items are focusable or not, I want to set focusability for a single item in the list, so that the selector seamlessly transitions from selecting the entire row for non-focusable items, and traversing the focus tree for items that contain focusable children.
Any takers?
This helped me.
In your manifest :
<activity android:name= ".yourActivity" android:windowSoftInputMode="adjustPan"/>
Sorry, answered my own question. It may not be the most correct or most elegant solution, but it works for me, and gives a pretty solid user experience. I looked into the code for ListView to see why the two behaviors are so different, and came across this from ListView.java:
public void setItemsCanFocus(boolean itemsCanFocus) {
mItemsCanFocus = itemsCanFocus;
if (!itemsCanFocus) {
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
}
}
So, when calling setItemsCanFocus(false), it's also setting descendant focusability such that no child can get focus. This explains why I couldn't just toggle mItemsCanFocus in the ListView's OnItemSelectedListener -- because the ListView was then blocking focus to all children.
What I have now:
<ListView
android:id="#android:id/list"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:descendantFocusability="beforeDescendants"
/>
I use beforeDescendants because the selector will only be drawn when the ListView itself (not a child) has focus, so the default behavior needs to be that the ListView takes focus first and draws selectors.
Then in the OnItemSelectedListener, since I know which header view I want to override the selector (would take more work to dynamically determine if any given position contains a focusable view), I can change descendant focusability, and set focus on the EditText. And when I navigate out of that header, change it back it again.
public void onItemSelected(AdapterView<?> listView, View view, int position, long id)
{
if (position == 1)
{
// listView.setItemsCanFocus(true);
// Use afterDescendants, because I don't want the ListView to steal focus
listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
myEditText.requestFocus();
}
else
{
if (!listView.isFocused())
{
// listView.setItemsCanFocus(false);
// Use beforeDescendants so that the EditText doesn't re-take focus
listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
listView.requestFocus();
}
}
}
public void onNothingSelected(AdapterView<?> listView)
{
// This happens when you start scrolling, so we need to prevent it from staying
// in the afterDescendants mode if the EditText was focused
listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
Note the commented-out setItemsCanFocus calls. With those calls, I got the correct behavior, but setItemsCanFocus(false) caused focus to jump from the EditText, to another widget outside of the ListView, back to the ListView and displayed the selector on the next selected item, and that jumping focus was distracting. Removing the ItemsCanFocus change, and just toggling descendant focusability got me the desired behavior. All items draw the selector as normal, but when getting to the row with the EditText, it focused on the text field instead. Then when continuing out of that EditText, it started drawing the selector again.
My task was to implement ListView which expands when clicked. The additional space shows EditText where you can input some text. App should be functional on 2.2+ (up to 4.2.2 at time of writing this)
I tried numerous solutions from this post and others I could find; tested them on 2.2 up to 4.2.2 devices.
None of solutions was satisfactionary on all devices 2.2+, each solution presented with different problems.
I wanted to share my final solution :
set listview to android:descendantFocusability="afterDescendants"
set listview to setItemsCanFocus(true);
set your activity to android:windowSoftInputMode="adjustResize"
Many people suggest adjustPan but adjustResize gives much better ux imho, just test this in your case. With adjustPan you will get bottom listitems obscured for instance. Docs suggest that ("This is generally less desirable than resizing"). Also on 4.0.4 after user starts typing on soft keyboard the screen pans to the top.
on 4.2.2 with adjustResize there are some problems with EditText focus. The solution is to apply rjrjr solution from this thread. It looks scarry but it is not. And it works. Just try it.
Additional 5. Due to adapter being refreshed (because of view resize) when EditText gains focus on pre HoneyComb versions I found an issue with reversed views:
getting View for ListView item / reverse order on 2.2; works on 4.0.3
If you are doing some animations you might want to change behaviour to adjustPan for pre-honeycomb versions so that resize doesnt fire and adapter doesn't refresh the views. You just need to add something like this
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
All this gives acceptable ux on 2.2 - 4.2.2 devices.
Hope it will save people some time as it took me at least several hours to come to this conclusion.
This saved my life--->
set this line
ListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Then in your manifest in activity tag type this-->
<activity android:windowSoftInputMode="adjustPan">
Your usual intent
We're trying this on a short list that does not do any view recycling. So far so good.
XML:
<RitalinLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/cart_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
/>
</RitalinLayout>
Java:
/**
* It helps you keep focused.
*
* For use as a parent of {#link android.widget.ListView}s that need to use EditText
* children for inline editing.
*/
public class RitalinLayout extends FrameLayout {
View sticky;
public RitalinLayout(Context context, AttributeSet attrs) {
super(context, attrs);
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
#Override public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) return;
View baby = getChildAt(0);
if (newFocus != baby) {
ViewParent parent = newFocus.getParent();
while (parent != null && parent != parent.getParent()) {
if (parent == baby) {
sticky = newFocus;
break;
}
parent = parent.getParent();
}
}
}
});
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override public void onGlobalLayout() {
if (sticky != null) {
sticky.requestFocus();
}
}
});
}
}
this post was matching exactly my keywords. I have a ListView header with a search EditText and a search Button.
In order to give focus to the EditText after loosing the initial focus the only HACK that i found is:
searchText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// LOTS OF HACKS TO MAKE THIS WORK.. UFF...
searchButton.requestFocusFromTouch();
searchText.requestFocus();
}
});
Lost lots of hours and it's not a real fix. Hope it helps someone tough.
If the list is dynamic and contains focusable widgets, then the right option is to use RecyclerView instead of ListView IMO.
The workarounds that set adjustPan, FOCUS_AFTER_DESCENDANTS, or manually remember focused position, are indeed just workarounds. They have corner cases (scrolling + soft keyboard issues, caret changing position in EditText). They don't change the fact that ListView creates/destroys views en masse during notifyDataSetChanged.
With RecyclerView, you notify about individual inserts, updates, and deletes. The focused view is not being recreated so no issues with form controls losing focus. As an added bonus, RecyclerView animates the list item insertions and removals.
Here's an example from official docs on how to get started with RecyclerView: Developer guide - Create a List with RecyclerView
some times when you use android:windowSoftInputMode="stateAlwaysHidden"in manifest activity or xml, that time it will lose keyboard focus. So first check for that property in your xml and manifest,if it is there just remove it. After add these option to manifest file in side activity android:windowSoftInputMode="adjustPan"and add this property to listview in xml android:descendantFocusability="beforeDescendants"
Another simple solution is to define your onClickListener, in the getView(..) method, of your ListAdapter.
public View getView(final int position, View convertView, ViewGroup parent){
//initialise your view
...
View row = context.getLayoutInflater().inflate(R.layout.list_item, null);
...
//define your listener on inner items
//define your global listener
row.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
doSomethingWithViewAndPosition(v,position);
}
});
return row;
That way your row are clickable, and your inner view too :)
The most important part is to get the focus working for the list cell.
Especially for list on Google TV this is essential:
setItemsCanFocus method of the list view does the trick:
...
mPuzzleList = (ListView) mGameprogressView.findViewById(R.id.gameprogress_puzzlelist);
mPuzzleList.setItemsCanFocus(true);
mPuzzleList.setAdapter(new PuzzleListAdapter(ctx,PuzzleGenerator.getPuzzles(ctx, getResources(), version_lite)));
...
My list cell xml starts like follows:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/puzzleDetailFrame"
android:focusable="true"
android:nextFocusLeft="#+id/gameprogress_lessDetails"
android:nextFocusRight="#+id/gameprogress_reset"
...
nextFocusLeft/Right are also important for D-Pad navigation.
For more details check out the great other answers.
I just found another solution. I believe it's more a hack than a solution but it works on android 2.3.7 and android 4.3 (I've even tested that good old D-pad)
init your webview as usual and add this: (thanks Michael Bierman)
listView.setItemsCanFocus(true);
During the getView call:
editText.setOnFocusChangeListener(
new OnFocusChangeListener(View view,boolean hasFocus){
view.post(new Runnable() {
#Override
public void run() {
view.requestFocus();
view.requestFocusFromTouch();
}
});
Just try this
android:windowSoftInputMode="adjustNothing"
in the
activity
section of your manifest.
Yes, it adjusts nothings, which means the editText will stay where it is when IME is opening. But that's just an little inconvenience that still completely solves the problem of losing focus.
In my case, there is 14 input edit text in the list view. The problem I was facing, when the keyboard open, edit text focus lost, scroll the layout, and as soon as focused view not visible to the user keyboard down. It was not good for the user experience. I can't use windowSoftInputMethod="adjustPan". So after so much searching, I found a link that inflates custom layout and sets data on view as an adapter by using LinearLayout and scrollView and work well for my case.

requestFocus doesn't work properly for EditText

A lot of time was spent to solve the problem, and it looks easy, but I'm really tired and couldn't find the solution.
I have an Activity, activity has 4 EditText components, 2 of them has popup menu (AlertDialog) which contain the list, next one - is disabled for edit, and last one - is editable, and should show the soft keyboard, when user is tapping on it.
Also, my root LinearLayout has LinearLayout which contain inside RelativeLayout. The last one is need for AdvBanner. Last LinearLayout(RelativeLayout) is aligned to the bottom of root layout.
The part of XML that describes it:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="bottom"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="bottom">
<RelativeLayout
android:id="#+id/AdvLayoutReserveArea"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="bottom" />
</LinearLayout>
When activity is start, editable EditText has focus with GREEN border and cursor is blinking. After few seconds left, the AdvBanner is loaded and shown. When it happens, editable EditText lost focus.. from this moment, my life be like a nightmare.
Let's look step by step.
Problem 1.
If in THIS MOMENT (when Adv loaded and appears) user is editing an EditText field via the soft keyboard, focus is lost, border take a GRAY color, and if user continue to typing a text is have no result - symbols are not printed (CURSOR in EditText is too lost).
I THINK any user will be annoyed - when you typing text, and cursor is inactive, because in background some adv is loaded and it take focus for self.
To solve this, in method when Adv is loaded (is shown) I try to back focus manually to EditText by requestFocus method.
public void onAdLoaded()
{
// TODO Auto-generated method stub
// add app specific code for this event here...
// called when an ad is successfully displayed on device
CountEdit1.requestFocus();
}
Yes, the cursor is returned to EditText field, and if soft keyboard is active, user can still typing text, but border of EditText field stay GRAY...
NOTE: actually I'm not sure about the difference between GREEN and GRAY border of focused EditText.. GREEN is usually when user is tapping on it, and GRAY, probably, when we want to request a focus manually (using requestFocus() etc)
Problem 2. (As result of solvation Problem #1).
After soft keyboard was closed, if user tap on editable EditText field, it take focus and cursor appears inside, but no reaction for showing soft keyboard again! Tapping of it do not show soft keyboard, but looks like the edit field in copy mode - when user can select a text and cut/copy it to clipboard.
My goal is easy for a first look. I just want to SAVE the cursor and focus to editable EditText field (CountEdit1) while soft keyboard is shown and user typing some text.
And normal reaction when user tapping EditText - as usually, just show me the soft keyboard!
I read all issues here, I combined different methods (clearFocus, requestFocusFromTouch etc), just not enough of time and space to describe all that I tried to do to solve this. The main problems are described above.
Hope for help and solving the problem...
Thanks in advance..
The goal is solved, the workaround is an easier than I thought. Problem #2 is fixed by using onClick () method. Sufficient condition for appearing of soft keyboard that use of both clearFocus() and requestFocus() methods.
CountEdit1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
CountEdit1.clearFocus();
CountEdit1.requestFocus();
}
});
The soft keyboard appears when user is tapping on the EditText field.
Fixed.
Works for me:
InputMethodManager mgr = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
editField.requestFocus();
mgr.showSoftInput(editField, InputMethodManager.SHOW_IMPLICIT);
userInput.post(new Runnable() {
public void run() {
userIdInput.requestFocus();
}
});
Have a go at this and tell if your problem is still unsolved.
You should request focus after view is created in fragment or activity:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
CountEdit1.requestFocus();
}
try this:
public void onAdLoaded()
{
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
CountEdit1.requestFocus();
InputMethodManager mgr = (InputMethodManager) base.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(CountEdit1, InputMethodManager.SHOW_IMPLICIT);
CountEdit1.setSelection(CountEdit1.getText().length());
}
},0);
}

Removing autofocus from EditText and regaining focus ?

I have an EditText and a set of Buttons in my layout.
To remove autofocus from EditText i am using a dummy LinearLayout as told in some answers at this site.
I want the edit text to get focus on button press and the virtual keyboard being shown.
but on 1st button press the edit text gets focus but virtual keyboard is shown only after button is pressed again.well the problem is bit different but any idea? This is what i m doing on button click:
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mgr.showSoftInput(main_edt,InputMethodManager.SHOW_FORCED);
main_edt.requestFocus();
}
});
This is the dummy linear layout:
<LinearLayout
android:focusable="true"
android:id="#+id/dummyll"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px" />
If i dont write this dummy linear layout or make the focusable tags as false the keyboard shows on 1st click only.
Let's try to set the below properties in your xml itself for EditText
android:focusableInTouchMode="true"
android:cursorVisible="false".
I hope it may solve your problem,if you suppose want to hide the softkeypad itself at launching activity means use the below code in your activity
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Add attribute android:windowSoftInputMode="stateHidden" to the activity in your manifest. This way, the soft keyboard will no be shown, when you start the activity.

Categories

Resources