ListView
Android では、ユーザー入力に基づいてフィルタリングし、表示される項目が値に基づいて動的に更新されるようにするにはどうすればよいですかTextView
?
次のようなものを探しています:
-------------------------
| Text View |
-------------------------
| List item |
| List item |
| List item |
| List item |
| |
| |
| |
| |
-------------------------
ベストアンサー1
まず、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 の上に適切な EditText が表示され、すべてが適切にレイアウトされます。次に、通常どおりに ListActivity を作成しますが、メソッドsetContentView()
に呼び出しを追加してonCreate()
、最近宣言したレイアウトを使用します。ListView
を で特別にID 付けしたことに注意してくださいandroid: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
。そのボックスに何かを実行させるには、そこから入力を取得し、その入力でリストをフィルターする必要があります。多くの人がこれを手動で実行しようとしましたが、ほとんど ListView
Adapter
Filter
クラスには、フィルタリングを自動的に実行するために使用できるオブジェクトが付属しています。EditText
からの入力を にパイプするだけです。これは非常に簡単です。簡単なテストを実行するには、呼び出しFilter
に次の行を追加します。onCreate()
adapter.getFilter().filter(s);
ListAdapter
これを機能させるには、 を変数に保存する必要があることに注意してください。私はArrayAdapter<String>
先ほど を「adapter」という変数に保存しました。
次のステップは から入力を取得することですEditText
。これは実際には少し考える必要があります。OnKeyListener()
に を追加することもできますEditText
。ただし、このリスナーはいくつかの重要な出来事. For example, if a user enters 'wyw', the predictive text will likely recommend 'eye'. Until the user chooses either 'wyw' or 'eye', your OnKeyListener
will not receive a key event. Some may prefer this solution, but I found it frustrating. I wanted every key event, so I had the choice of filtering or not filtering. The solution is a TextWatcher
. Simply create and add a TextWatcher
to the EditText
, and pass the ListAdapter
Filter
a filter request every time the text changes. Remember to remove the TextWatcher
in OnDestroy()
! Here is the final solution:
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);
}