2

ArrayAdapter を拡張するカスタム アダプターを持つ ListView があります。アーティスト型の ArrayAdapter です。

アーティストは、名前と ID を持つ非常に小さなクラスです。Artist クラスは、名前だけを返すように toString() をオーバーライドする必要があります。

私はEditTextを持っています。EditText には TextChangeListener があり、アダプターで .getFilter().filter(chars, callback) を呼び出します。

Filter.Filterlistener().onComplete() コールバックで、カウントを出力すると、非常によく見えます。入力すると、カウントが減少します。したがって、すべてが宣伝どおりに機能しますが、リストは同じままです。リストを強制的に再描画するために artistAdapter.notifyDataSetChanged() を呼び出そうとしましたが、何も起こりません。[2.)を参照]

私は今何日もいじっています!私は絶望的です.誰かが私のコードを見て、私が間違っていることを教えてくれることを願っています!

ありがとう!

これが私がやったことです:

1.) ListView と EditText を次のように定義します。

<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.) アクティビティ onCreate() で ListView をセットアップします。

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.) これは私の ArtistAdapter です。remove() および add() メソッドを追加しました。

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.) 私のアーティストは toString() もオーバーライドしています:

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;
    }
}
4

3 に答える 3

4

私は解決策を見つけました。コード全体を最初から書き直して、問題を見つけました。

ArtistAdapterと呼ばれる私のカスタムArrayAdapter(問題の3.を参照)で、アイテムを格納する変数がある場合:プライベートリストアイテム。

そして、オーバーライドされたgetView()で、現在のアイテムを取得したいときに、items.getItem(position)を実行します。getItems(position)を実行します(したがって、アイテムは、自分のアイテムではなく、基本クラスのストレージから取得されます。 )そしてこれはトリックを行うようです!

これは、現在のgetView()です(動作しているバージョン):

@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、これは本当に厄介なバグでした...

于 2010-03-30T14:44:59.243 に答える
1

アダプターフィルターではなく、listView.setFilterText()を使用してみてください。

于 2010-03-24T09:42:42.690 に答える
1

toString()フィルタリングするテキストを返すには、メソッドをオーバーライドする必要があります。

于 2010-11-26T17:05:58.540 に答える