Reputation: 1922
In my application I want to display a list of stuff and provide the user with the ability to filter the list by using the soft keyboard. To that end I added a button that should trigger (hide/show) the soft keyboard for filtering. I don't want to have a visible edit text control, cause it would take up unnecessary space. Rather than that, I would like to display a toast showing the filter query as the user types, much as the 'android:textFilterEnabled' attribute for ListView does. To my understanding there is no obvious way of doing this with available Android components. So I tried the following approach:
1) creating a layout containing invisible edit text and the list view:
<ListView android:id="@+id/main_list"
android:drawSelectorOnTop="false"
android:layout_height="0px"
android:layout_width="fill_parent"
android:layout_weight="5"
/>
2) adding button as a popup and invoking InputMethodManager on click to toggle the soft input (called in onCreate):
private void initButton() {
Button buttonView = (Button) getLayoutInflater().inflate(R.layout.keyboard_button, null);
buttonView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final View target = findViewById(R.id.filterbox);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// this does not work...
// imm.toggleSoftInputFromWindow(target.getWindowToken(), InputMethodManager.SHOW_FORCED, 0);
// ... so need to track this in an instance variable - which sucks
if (imeShowing) {
imm.hideSoftInputFromWindow(target.getWindowToken(), 0);
imeShowing = false;
} else {
// check that the filterbox got focus
Preconditions.checkState(target.requestFocusFromTouch());
Preconditions.checkState(target.hasWindowFocus());
Preconditions.checkState(target.hasFocus());
imm.showSoftInput(target, 0);
imeShowing = true;
}
}
});
buttonPopup = new PopupWindow(buttonView);
// ... code to display the button as a small popup
}
As mentioned in the code sample, the 'obvious' approach (calling toggleSoftInput) does not work, so I had to revert to this ugly if-else. This is however, a secondary problem. The primary problem is that when I run this in the emulator, the soft keyboard is displayed correctly, but as soon as I start typing in it, the systems starts an intent to the google search activity! And the typed characters appear in the Google search box displayed as a result. What is even more weird, this only happens the first time I type after deploying and running the app. I.e. if I go back to my app from the Google search box, everything works as expected (no redirects to the search box). Before showing the display I make sure that the invisible edittext gets focus, so it should be the target of the soft keyboard, right??
Does anyone have any idea what is happening here?
Upvotes: 1
Views: 2199
Reputation: 51
Sorry this is me (the author of this question), I can't access my old account due to SO new 'awesome' OpenID login:/
So I figured out that what I really need to do is just turn on the 'android:textFilterEnabled' attribute of the list, and focus on it on the button click. ListView supports input from soft keyboard (although I figured it out by looking at the actual code of AbsListView rather than getting hints in any documentation:). Also, I managed to get PopupWindow working for the button (instead of Dialog that I tried previously) so the focus problem is gone. The working code for this (in case anyone has similar problem) below:
View popupView = getLayoutInflater().inflate(R.layout.keyboard_button, null);
Button buttonView = (Button) popupView.findViewById(R.id.keyboardButton);
buttonView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final View list = findViewById(R.id.the_list);
list.requestFocus();
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
buttonPopup = new PopupWindow(this);
The list will handle input from soft keyboard just as it does from hard one. The trick is just to trigger the keyboard and focus on the list. Also you may control how the filtering is applied to the list by setting a custom QueryFilterProvider on its associated adapter.
Upvotes: 1