如何在getView()之前过滤Basedapter中的listView?

How to filter listView in Basedapter before getView()?

有很多关于如何根据 EditText 中的用户输入过滤 listView 的教程:最初我有我的整个列表,在输入时正在减少。

我需要做不同的事情:当 Activity 启动时,没有 listView,但是当用户输入匹配列表中的任何项目时,会出现 listView。问题是:我的 getView() 要么在开始时膨胀所有可用的东西(没有过滤),要么导致 NullPointerException 如果我在开始时引用过滤结果。

解决方案似乎很明显,但就我的第一个应用程序而言,我无法想出它。

我的Activity:

public class AddTask extends Activity implements View.OnClickListener {

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

    EditText addTagHere = (EditText) findViewById(R.id.addTagHere);
    addTagHere.addTextChangedListener(new TagWatcher(addTagHere));

    GridView autocompleteTagGrid = (GridView) findViewById(R.id.autocomplete_tag_grid);
    TagAdapter tagAdapter = new TagAdapter(this);
    autocompleteTagGrid.setAdapter(tagAdapter);

    autocompleteTagGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            my_method_here;
        }
    });
}

public class TagWatcher implements TextWatcher {

    public EditText editText;

    public TagWatcher(EditText editText) {
        super();
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        tagAdapter.getFilter().filter(s);
        tagAdapter.notifyDataSetChanged();
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
}

我的适配器:

public class TagAdapter extends BaseAdapter implements Filterable {

private Context context;
LayoutInflater inflater;
List<MyTag> tags = getTagList();
List<MyTag> filteredTags;
TextView tagBubble;

public TagAdapter(Context context) {
    this.context = context;
    inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = inflater.inflate(R.layout.tag_bubble, null);
    }
    tagBubble = (TextView) convertView.findViewById(R.id.one_tag_bubble);
    tagBubble.setText(filteredTags.get(position).getMyTag());

    return convertView;
}

@Override
public int getCount() {
    return tags.size();
}

@Override
public Object getItem(int position) {
    return tags.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

public List<MyTag> getTagList() {
    List<MyTag> tags = new ArrayList<>();
    SQLiteDatabase db = DBHelper.getHelper(context).getReadableDatabase();
    Cursor cursor = db.query(some query);
    if (cursor != null && cursor.moveToFirst()) {
        for (int i = 0; i < cursor.getCount(); i++) {
            MyTag oneTag = new MyTag();
            oneTag.setIdTag(cursor.getInt(cursor.getColumnIndex(DBHelper.COLUMN_ID)));
            oneTag.setMyTag(cursor.getString(cursor.getColumnIndex(DBHelper.COLUMN_TAG)));
            tags.add(oneTag);
            cursor.moveToNext();
        }
        cursor.close();
        db.close();
    }
    return tags;
}

public Filter getFilter() {
    return new InputFilter();
}

public class InputFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence beginning) {

        FilterResults results = new Filter.FilterResults();

        if (beginning == null || beginning.length() < 3) {
            results.values = null;
            results.count = 0;
        } else {
            filteredTags = new ArrayList<>();

            for (MyTag p : tags) {
                if (p.getMyTag().toUpperCase().contains(beginning.toString().toUpperCase()))
                    filteredTags.add(p);
            }
            results.values = filteredTags;
            results.count = filteredTags.size();
        }
        return results;
    }

    @Override
    protected void publishResults(CharSequence beginning, FilterResults results) {

        if (results.count == 0) {
            notifyDataSetInvalidated();
        } else {
            tags = (List<MyTag>) results.values;
            notifyDataSetChanged();
        }
    }
}

你在适配器中使用了这么多复杂的机制。只需使用两个 arraylist ,一个将保留整个数据。迭代它以匹配搜索的单词。如果任何元素包含搜索到的词,只需将其添加到第二个列表,并显示第二个列表的所有项目。在适配器 class 本身中调用 notifyDataSetChanged()。希望对你有帮助