我有一个带有自定义适配器的listView。 我的活动中有一个编辑文本视图,用户可以在其中键入以过滤列表视图中的内容。
让我们说列表视图中有两个项目。执行过滤后,ArrayList减少为一个元素。 问题是仍然为前两行执行了getView方法。
这是我的代码。
ListActivity:
public class TeamsListActivity extends ListActivity {
private ArrayList<Team> teams = new ArrayList<Team>();
private TeamsListAdapter teamsListAdapter = null;
private EditText searchInput = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.teams_list);
// get association id from the intent.
int afId = getIntent().getExtras().getInt("afId");
Log.i(MainActivity.TAG, "id_association =" + afId);
// get the teams from the association.
this.teams = TeamsDAO.getInstance(getApplicationContext())
.getTeamsByAssociation(afId);
// inits the list adapter
teamsListAdapter = new TeamsListAdapter(this, teams);
setListAdapter(teamsListAdapter);
// gets the search input view
searchInput = (EditText) findViewById(R.id.teams_list_search_box);
searchInput.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
Log.d(Constants.TAG,"Teams search: " + s.toString());
teamsListAdapter.getFilter().filter(s);
}
});
}
}
我的适配器
public class TeamsListAdapter extends ArrayAdapter<Team> implements Filterable {
private ArrayList<Team> teams = null;
private Context context = null;
public TeamsListAdapter(Context context,
ArrayList<Team> objects) {
super(context, R.layout.teams_list_row, objects);
this.context = context;
this.teams = objects;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
if (v == null) {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.teams_list_row, null);
}
Team t = teams.get(position);
if (t != null) {
TextView txtTeamName = (TextView) v.findViewById(R.id.teams_list_team_name);
txtTeamName.setText(t.getName());
ImageView ivTeamLogo = (ImageView) v.findViewById(R.id.teams_list_team_logo);
ivTeamLogo.setImageResource(R.drawable.af_braga);
}
return v;
}
@Override
public Filter getFilter() {
return new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Log.d(Constants.TAG, "**** Search RESULTS for: " + constraint);
teams = (ArrayList<Team>) results.values;
Log.d(Constants.TAG,"size:"+teams.size());
TeamsListAdapter.this.notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
Log.d(Constants.TAG, "**** PERFORM TEAK FILTERING for: " + constraint);
ArrayList<Team> filteredResults = getFilteredResults(constraint);
FilterResults results = new FilterResults();
results.values = filteredResults;
return results;
}
/**
* filters the teamsList
* @param constraint String The text to search
* @return ArrayList<Team>
*/
private ArrayList<Team> getFilteredResults(CharSequence constraint) {
ArrayList<Team> teams = TeamsListAdapter.this.teams;
ArrayList<Team> filteredTeams = new ArrayList<Team>();
for(int i=0;i< teams.size();i++){
if(teams.get(i).getName().toLowerCase().startsWith(constraint.toString().toLowerCase())){
filteredTeams.add(teams.get(i));
}
}
return filteredTeams;
}
};
}
}
澄清问题。
1.但是我的名单开始显示两个元素。 2.用户在编辑文本中插入一些文本以过滤列表内容,这导致更新的arrayList只有一个与查询匹配的元素。 3.在调用notifyDataSetChanged后,getView仍被调用,就像数据集中有两行在执行Team t = teams.get(position)时导致IndexOutOfBoundsException,因为arrayList现在只有一个元素,所以当position = 1 =&gt; get(postion)失败。
希望现在明白。
答案 0 :(得分:2)
我解决了我的问题。 我需要像我这样在我的适配器中覆盖几个方法。
@Override
public int getCount() {
return teams.size();
}
@Override
public Team getItem(int position) {
return teams.get(position);
}
@Override
public long getItemId(int position) {
return teams.get(position).getId();
}
现在我发现我的搜索实施存在问题。因为我正在更新原始数据集,所以搜索只能工作一次。如果我试图回到原始列表我不能因为我的原始数据数组已被修改。使用数据库查询而不是过滤数组列表很容易解决。
答案 1 :(得分:0)
我认为你不需要
teams =(ArrayList)results.values;
在publishResults函数中。