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.
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: 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.
You are a lifessaver. I was stuck on this for so long. – metalideath Feb 8 '11 at 4:52 very cool, didn't tested yet.
Have you tested on 1.5, 1.6 and 3.0? – Rafael Sanches May 3 '11 at 8:33 Rafael Sanches: I haven't touched the project since 2.1, but at that time, it was confirmed working in 1.5, 1.6, and 2.1. I make no guarantee that it still works in 2.2 or later. – Joe May 9 '11 at 13:52 1 only needed android:descendantFocusability="afterDescendants" - anyway +1 – kellogs May 26 '11 at 15:56 @kellogs: yeah, descendantFocusability="afterDescendants" will allow your EditText to take focus inside the ListView, but then you get no list item selector while navigating with a dpad.
My task was to have the list item selector on all rows except the one with the EditText. Glad it helped though. FWIW, we ended up reevaluating this implementation and decided that a focusable inside a ListView is just not idiomatic-Android UI design, so we scrapped the idea in favor of a more-Android-friendly approach.
– Joe May 26 '11 at 23:37.
1 I'm not sure I see the relevance. Setting windowSoftInputMode just changes the way the IME adjusts the rest of the window contents when it is open. It doesn't allow you to selectively change the focus type of the ListView.
Can you explain a bit more, how this relates to the initial use case? – Joe Feb 7 '11 at 16:14 @Joe When the IME is opened, the cursor - and probably the focus, too - just jumps around in my screen, making it impossible to input text. Your OnItemSelectedListener doesn't change that.
However Iogan's simple solution works like a charm, thanks! – Gubbel May 16 '11 at 21:13 @Gubbel: Indeed, it wouldn't change that at all, because the original question was about something entirely different :) Glad logan's fix works for what you were looking for, but it simply is not even remotely related to the question. – Joe May 27 '11 at 3:48 3 Using this plus Joe's android:descendantFocusability property got my EditTexts inside of a ListView resolving the keyboard properly, upvoted both.
Android:descendantFocusability by itself didn't do the trick and I wasn't remotely enthusiastic about @Overriding onItemSelected for all 14 EditTexts I have to deal with. :) Thanks! – Thomson Comer Jul 31 '11 at 15:22.
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.
You're my hero! – dziobas Mar 30 '11 at 15:40.
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 question relates to focus, not clickability. – Joe Oct 11 '11 at 16:26.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.