web-dev-qa-db-ja.com

AndroidでListViewを動的に更新する方法

Androidでは、表示されるアイテムがListView値に基づいて動的に更新されるユーザー入力に基づいてフィルタリングするTextViewをどのように使用できますか?

私はこのようなものを探しています:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
159
Hamy

最初に、EditTextとListViewの両方を持つXMLレイアウトを作成する必要があります。

<LinearLayout 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical" >

    <!-- Pretty hint text, and maxLines -->
    <EditText Android:id="@+building_list/search_box" 
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:hint="type to filter"
        Android:inputType="text"
        Android:maxLines="1"/>

    <!-- Set height to 0, and let the weight param expand it -->
    <!-- Note the use of the default ID! This lets us use a 
         ListActivity still! -->
    <ListView Android:id="@Android:id/list"
        Android:layout_width="fill_parent"
        Android:layout_height="0dip"
        Android:layout_weight="1" 
         /> 

</LinearLayout>

これにより、ListViewの上にNice EditTextが表示され、すべてが適切にレイアウトされます。次に、通常どおりListActivityを作成しますが、setContentView()メソッドにonCreate()呼び出しを追加して、最近宣言したレイアウトを使用します。 ListViewAndroid:id="@Android:id/list"で特別に識別したことに注意してください。これにより、ListActivityは、宣言されたレイアウトで使用するListViewを知ることができます。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.filterable_listview);

        setListAdapter(new ArrayAdapter<String>(this,
                       Android.R.layout.simple_list_item_1, 
                       getStringArrayList());
    }

ここでアプリを実行すると、前のListViewが表示され、上にNiceボックスが表示されます。そのボックスに何かをさせるには、そのボックスから入力を取得し、その入力にリストをフィルターさせる必要があります。多くの人がこれを手動で実行しようとしましたが、mostListViewAdapterクラスには、フィルタリングを自動的に実行するために使用できるFilterオブジェクトが付属しています。入力をEditTextからFilterにパイプするだけです。それは非常に簡単です。クイックテストを実行するには、この行をonCreate()呼び出しに追加します

adapter.getFilter().filter(s);

この作業を行うには、ListAdapterを変数に保存する必要があることに注意してください。以前のArrayAdapter<String>を 'adapter'という変数に保存しました。

次のステップは、EditTextから入力を取得することです。これには実際に少し考えが必要です。 EditTextOnKeyListener()を追加できます。ただし、このリスナーは一部のキーイベントのみを受け取ります。たとえば、ユーザーが「wyw」と入力すると、予測テキストは「eye」を推奨します。ユーザーが「wyw」または「eye」を選択するまで、OnKeyListenerはキーイベントを受け取りません。このソリューションを好む人もいるかもしれませんが、イライラすることがわかりました。すべての重要なイベントが欲しかったので、フィルタリングするかしないかの選択がありました。解決策はTextWatcherです。 TextWatcherを作成してEditTextに追加し、テキストが変更されるたびにListAdapterFilterにフィルターリクエストを渡すだけです。 OnDestroy()TextWatcherを忘れずに削除してください!最終的な解決策は次のとおりです。

private EditText filterText = null;
ArrayAdapter<String> adapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.filterable_listview);

    filterText = (EditText) findViewById(R.id.search_box);
    filterText.addTextChangedListener(filterTextWatcher);

    setListAdapter(new ArrayAdapter<String>(this,
                   Android.R.layout.simple_list_item_1, 
                   getStringArrayList());
}

private TextWatcher filterTextWatcher = new TextWatcher() {

    public void afterTextChanged(Editable s) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before,
            int count) {
        adapter.getFilter().filter(s);
    }

};

@Override
protected void onDestroy() {
    super.onDestroy();
    filterText.removeTextChangedListener(filterTextWatcher);
}
286
Hamy

プログラムを実行すると、強制終了します。

私は行を交換しました:

Android:id = "@ + building_list/search_box"

Android:id = "@ + id/search_box"

それが問題なのでしょうか? 「@ + building_list」とは何ですか?

10
j7nn7k

私はフィルタリングに問題があり、その結果はフィルタリングされましたが、復元されません

フィルタリング(アクティビティ開始)の前にリストバックアップを作成しました。(同じデータを含む別のリストのみ)

フィルター処理では、フィルターとリストアダプターはプライマリリストに接続されます。

ただし、フィルター自体はバックアップリストのデータを使用しました。

これにより、リストがすぐに更新され、search-term-charactersを削除しても、リストはすべてのケースで正常に復元されます。

とにかくこのソリューションをありがとう。

4
cV2