1

私のアプリケーションでは、もののリストを表示し、ユーザーがソフト キーボードを使用してリストをフィルター処理できるようにしたいと考えています。そのために、フィルタリング用のソフト キーボードをトリガー (非表示/表示) するボタンを追加しました。不必要なスペースを占有するため、編集テキスト コントロールを表示したくありません。それよりも、ListView の 'android:textFilterEnabled' 属性と同じように、フィルター クエリを表示するトーストを表示したいと思います。私の理解では、利用可能な Android コンポーネントでこれを行う明白な方法はありません。そこで、次のアプローチを試しました。

1) 非表示の編集テキストとリスト ビューを含むレイアウトの作成:

<ListView android:id="@+id/main_list"
          android:drawSelectorOnTop="false"
          android:layout_height="0px"
          android:layout_width="fill_parent"
          android:layout_weight="5"
          />

2) ボタンをポップアップとして追加し、クリック時に InputMethodManager を呼び出してソフト入力を切り替えます (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
}

コード サンプルで述べたように、「明白な」アプローチ (toggleSoftInput を呼び出す) は機能しないため、この醜い if-else に戻らなければなりませんでした。ただし、これは二次的な問題です。主な問題は、エミュレーターでこれを実行すると、ソフト キーボードが正しく表示されますが、入力を開始するとすぐに、システムが Google 検索アクティビティへのインテントを開始することです! 入力した文字は、結果として表示される Google 検索ボックスに表示されます。さらに奇妙なことに、これは、アプリを展開して実行した後、最初に入力したときにのみ発生します。つまり、Google 検索ボックスからアプリに戻ると、すべてが期待どおりに機能します (検索ボックスへのリダイレクトはありません)。ディスプレイを表示する前に、目に見えない edittext にフォーカスがあることを確認します。それで、ソフト キーボードのターゲットになるはずですよね??

ここで何が起こっているのか誰にも分かりませんか?

4

1 に答える 1

1

申し訳ありませんが、これは私(この質問の作成者)です。新しい「素晴らしい」OpenIDログインのため、古いアカウントにアクセスできません:/

だから私は本当に必要なことは、リストの 'android:textFilterEnabled' 属性をオンにして、ボタンのクリックに焦点を当てることであることがわかりました。ListView はソフト キーボードからの入力をサポートしています (ただし、ドキュメントでヒントを得るのではなく、AbsListView の実際のコードを見て理解しました:)。また、(以前に試したダイアログの代わりに)ボタンに対してPopupWindowを機能させることができたので、フォーカスの問題はなくなりました。以下のこのための作業コード(誰かが同様の問題を抱えている場合):

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);

リストは、ハード キーボードからの入力と同様に、ソフト キーボードからの入力も処理します。トリックは、キーボードをトリガーしてリストに集中することです。また、関連するアダプターにカスタム QueryFilterProvider を設定することで、リストにフィルターを適用する方法を制御することもできます。

于 2011-02-15T12:48:28.140 に答える