Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First, you need to create an XML layout that has both an EditText, and a ListView. </p> <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" &gt; &lt;!-- Pretty hint text, and maxLines --&gt; &lt;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"/&gt; &lt;!-- Set height to 0, and let the weight param expand it --&gt; &lt;!-- Note the use of the default ID! This lets us use a ListActivity still! --&gt; &lt;ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /&gt; &lt;/LinearLayout&gt; </code></pre> <p>This will lay everything out properly, with a nice EditText above the ListView. Next, create a ListActivity as you would normally, but add a <code>setContentView()</code> call in the <code>onCreate()</code> method so we use our recently declared layout. Remember that we ID'ed the <code>ListView</code> specially, with <code>android:id="@android:id/list"</code>. This allows the <code>ListActivity</code> to know which <code>ListView</code> we want to use in our declared layout. </p> <pre><code> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); setListAdapter(new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_list_item_1, getStringArrayList()); } </code></pre> <p>Running the app now should show your previous <code>ListView</code>, with a nice box above. In order to make that box do something, we need to take the input from it, and make that input filter the list. While a lot of people have tried to do this manually, <em>most</em> <code>ListView</code> <code>Adapter</code> classes come with a <code>Filter</code> object that can be used to perform the filtering automagically. We just need to pipe the input from the <code>EditText</code> into the <code>Filter</code>. Turns out that is pretty easy. To run a quick test, add this line to your <code>onCreate()</code> call</p> <pre><code>adapter.getFilter().filter(s); </code></pre> <p>Notice that you will need to save your <code>ListAdapter</code> to a variable to make this work - I have saved my <code>ArrayAdapter&lt;String&gt;</code> from earlier into a variable called 'adapter'.</p> <p>Next step is to get the input from the <code>EditText</code>. This actually takes a bit of thought. You could add an <code>OnKeyListener()</code> to your <code>EditText</code>. However, this listener only receives <em>some key events</em>. For example, if a user enters 'wyw', the predictive text will likely recommend 'eye'. Until the user chooses either 'wyw' or 'eye', your <code>OnKeyListener</code> 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 <code>TextWatcher</code>. Simply create and add a <code>TextWatcher</code> to the <code>EditText</code>, and pass the <code>ListAdapter</code> <code>Filter</code> a filter request every time the text changes. Remember to remove the <code>TextWatcher</code> in <code>OnDestroy()</code>! Here is the final solution:</p> <pre><code>private EditText filterText = null; ArrayAdapter&lt;String&gt; 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&lt;String&gt;(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); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload