如何在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()。希望对你有帮助
有很多关于如何根据 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()。希望对你有帮助