English 中文(简体)
How to dynamically update a ListView on Android [closed]
原标题:

On Android, how can I a ListView that filters based on user input, where the items shown are updated dynamically based on the TextView value?

I m looking for something like this:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
最佳回答

First, you need to create an XML layout that has both an EditText, and a ListView.

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

This will lay everything out properly, with a nice EditText above the ListView. Next, create a ListActivity as you would normally, but add a setContentView() call in the onCreate() method so we use our recently declared layout. Remember that we ID ed the ListView specially, with android:id="@android:id/list". This allows the ListActivity to know which ListView we want to use in our declared layout.

    @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());
    }

Running the app now should show your previous ListView, 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, most ListView Adapter classes come with a Filter object that can be used to perform the filtering automagically. We just need to pipe the input from the EditText into the Filter. Turns out that is pretty easy. To run a quick test, add this line to your onCreate() call

adapter.getFilter().filter(s);

Notice that you will need to save your ListAdapter to a variable to make this work - I have saved my ArrayAdapter<String> from earlier into a variable called adapter .

Next step is to get the input from the EditText. This actually takes a bit of thought. You could add an OnKeyListener() to your EditText. However, this listener only receives some key events. 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);
}
问题回答

running the programm will cause a force close.

I swaped the line:

android:id="@+building_list/search_box"

with

android:id="@+id/search_box"

could that be the problem? What is the @+building_list for?

i had a problem with filtering, that results have been filtered, but not restored!

so before filtering (activity start) i created a list backup.. (just another list, containing the same data)

on filtering, the filter and listadapter is connected to the primary list.

but the filter itself used the data from the backuped list.

this ensured in my case, that the list was updated immediately and even on deleting search-term-characters the list gets restored successfully in every case :)

thanks for this solution anyways.





相关问题
Android - ListView fling gesture triggers context menu

I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

Android intent filter for a particular file extension?

I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...

Android & Web: What is the equivalent style for the web?

I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...

TiledLayer equivalent in Android [duplicate]

To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?

Using Repo with Msysgit

When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error: /c/Users/Andrew Rabon/bin/repo: line ...

Android "single top" launch mode and onNewIntent method

I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...

From Web Development to Android Development

I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ? Also what new languages would I ...

热门标签