views:

483

answers:

4

I have a ListView with a custom Adapter that extends ArrayAdapter. It's a ArrayAdapter of Type Artist.

Artist is a very small class that has a name and an id. The Artist Class has toString() overridden to return just the name.

I have an EditText. The EditText has an TextChangeListener where i call .getFilter().filter(chars, callback) on my adapter.

In the Filter.Filterlistener().onComplete() callback i print the count and it looks really good. As i type the count decreases. So it seams everything works as advertised, but the List stays the same. I tried to call artistAdapter.notifyDataSetChanged() to force the list to redraw, but nothing happens. [see 2.)]

I am tinkering around for days now! I am desperate.. Hopefully someone can have a look on my code and tell me what i am doing wrong!

Thanks!

Here is what i have done:

1.) Defined a ListView and an EditText like this:

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_search_text"
    android:layout_width="fill_parent"
    android:layout_height="35dip"
    android:layout_below="@id/header">
</EditText>       
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_search"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</ListView>

2.) Setup my ListView in the Activities onCreate():

private ListView listView = null;
private ArtistAdapter artistAdapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search_artists);

    artistAdapter = new ArtistAdapter(this, R.layout.row, list); // 'list' is an ArrayList<Artist>

    listView = (ListView) findViewById(R.id.list_search);
    listView.setAdapter(artistAdapter);
    listView.setFastScrollEnabled(true);
    listView.setTextFilterEnabled(true);

    listView.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int position, long id) {
            // do something
        }
    });

    EditText txtSearch = (EditText) findViewById(R.id.list_search_text);
    txtSearch.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable arg0) { }

        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }

        public void onTextChanged(CharSequence chars, int start, int before, int count) {
            artistAdapter.getFilter().filter(chars, new Filter.FilterListener() {
                public void onFilterComplete(int count) {
                    Log.d(Config.LOG_TAG, "filter complete! count: " + count);
                    artistAdapter.notifyDataSetChanged();
                }
            });
        }
    });
}

3.) This is my ArtistAdapter in short. I added an remove() and add() method:

public class ArtistAdapter extends ArrayAdapter<Artist> implements SectionIndexer {
    private List<Artist> items;

    /* other stuff like overridden getView, getPositionForSection, getSectionForPosition and so on */

    @Override
    public void remove(Artist object) {
        super.remove(object);
        items.remove(object);
    }

    @Override
    public void add(Artist object) {
        super.add(object);
        items.add(object);
    }
}    

4.) My artist has also the toString() overridden:

public class Artist implements Comparable<Artist> {
    public String   uid;
    public String   name;

    public Artist(String id, String name) {
        this.uid = id;
        this.name = name;
    }

    public int compareTo(Artist another) {
        return this.name.compareToIgnoreCase(another.name);
    }

    @Override
    public String toString() {
        return this.name;
    }
}
A: 

Try using listView.setFilterText() rather then adapter filter.

Karan
I tried using .setFilterText() but nothing happens.and i looked at .setFilterText(): for it to work, the adapter must implement the Filterable Interface, and this interface just defines the .getFilter() method i use above. So you solution is doing the same as mine (or to be precise: it is doing the same NOT, exactly like mine) any other ideas?
Anton
Is it giving the proper count value in the FilterListener ?
Karan
Hi Karan! Yes, in the FilterListeners onFilterComplete() i have the proper count value! Any ideas why the listView does not get updated?
Anton
A: 

i have similar problem, the diference is i dont need to have a editview.

Thiago Diniz
A: 

I found the solution. I have rewritten the whole code from scratch and found the problem.

In my custom ArrayAdapter called ArtistAdapter (see 3. in question) if have a var to store the items: private List items;

And in my overridden getView() when i want to get the current item i did: items.getItem(position) now i do a: getItems(position) (so the item is retrieved from the storage of the base class and not my own) and this seems to do the trick!

This is my getView() as it is now (the version, that is working):

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LinearLayout artistView;
    Artist art = getItem(position);

    if (convertView == null) {
        artistView = new LinearLayout(getContext());
        String inflater = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater vi;
        vi = (LayoutInflater)getContext().getSystemService(inflater);
        vi.inflate(resId, artistView, true);
    } else {
        artistView = (LinearLayout) convertView;
    }
    TextView nameView = (TextView)artistView.findViewById(R.id.txt_name);
    TextView uidView = (TextView)artistView.findViewById(R.id.txt_uid);
    nameView.setText(art.name);
    uidView.setText(art.uid);
    return artistView;
}

Pfu, this was a really annoying bug...

Anton
A: 

Hi I have the same problem, i´ve implemented your solution and doesn´t work, it filter but nothing show.. i think it´s because i have to specify with which textview it have to compare the filter.. if you can post your Layout.row it would be great or if you can send me the entire project would be better