我的布局中的ListView控件顶部有一个EditText控件。此布局将加载到Fragment派生类中。我还将TextWatcher接口与EditText控件相关联,以便每次将文本输入EditText时,ListView都会根据输入文本过滤数据。 ListView的适配器通过重写GetFilter来实现Filterable行为。我正在描述的Fragment类是FragmentTabHost控件的一部分,后者又在运行时加载了3个选项卡。
根据我在EditText控件中输入的内容过滤列表可以正常工作。我面临的问题是,当我点击其他选项卡然后回到我的带有TextWat的TextTxt的Tab时,它不会清除之前输入的文本。我还注意到过滤后的列表现在是空的。一旦我从EditText手动删除了以前的文本,List就会重新显示旧数据。
当我选出当前片段时,请告诉我如何重置过滤器并清除EditText控件中的文本。基本上我不希望每次单击片段时EditText控件和Filter都保留旧的上下文。我已经粘贴了片段和列表适配器中的部分代码。
由于 巴拉吉
public class Favourites extends Fragment implements LoaderCallbacks<Cursor> {
ListView listView1;
ArrayList<FavouriteSearchResults> searchResults;
FavouritesBaseAdapter customAdapter;
private ProgressBar progressBar;
private EditText editText;
final int MENU_MAKE_CALL = 100;
final int MENU_SEND_MESSAGE = 101;
final int MENU_SEND_DIAL = 102;
final int MENU_COPY_CLIP = 103;
final int MENU_SEND_NUMBER = 104;
final int MENU_VIEW_CONTACT = 105;
private static final int LIST_ID = 1004;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setHasOptionsMenu(true); //Call this so that onCreateOptionsMenu is called
}
private class MyFocusChangeListener implements OnFocusChangeListener {
Context mContext;
public MyFocusChangeListener(Context context) {
mContext = context;
}
public void onFocusChange(View v, boolean hasFocus){
if(v.getId() == R.id.txtSearch && !hasFocus) {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.favourites, container, false);
editText = (EditText) v.findViewById(R.id.txtSearch);
OnFocusChangeListener ofcListener = new MyFocusChangeListener(getActivity());
editText.setOnFocusChangeListener(ofcListener);
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
customAdapter.getFilter().filter(cs);
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if(charSequence == null || charSequence.length() == 0) {
results.values = searchArrayList; //Return original list if search is cleared
results.count = searchArrayList.size();
}
else {
ArrayList<FavouriteSearchResults> tempResults = new ArrayList<FavouriteSearchResults>();
for(int i = 0;i < searchArrayList.size();i++) {
FavouriteSearchResults favResults = searchArrayList.get(i);
String sContactName = favResults.GetName();
String sId = favResults.GetId();
String searchChar = charSequence.toString();
if (sContactName.toLowerCase().contains(searchChar.toLowerCase())) {
FavouriteSearchResults newFavResults = new FavouriteSearchResults(sContactName);
newFavResults.SetId(sId);
tempResults.add(newFavResults);
}
}
results.values = tempResults;
results.count = tempResults.size();
}
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
//Set the filtered list into our copy list
searchFilteredArrayList = (ArrayList<FavouriteSearchResults>)filterResults.values;
notifyDataSetChanged();
}
};
答案 0 :(得分:2)
首先,我要指出您的getFilter()
方法非常无效。每次用户键入/删除一个字母时,它都会创建新的Filter
。这对垃圾收集器来说非常紧张。相反,我建议在您的片段中创建Filter
实例,并以getFilter()
方法返回此实例。
另外,如果你真的想清除编辑文本并重置过滤器 - 我会在你的片段实现中覆盖onDestroyView
方法并在那里做那些事情。
@Override
public void onDestroyView() {
editText.setText("");
editText.setOnFocusChangeListener(null);
super.onDestroyView();
}
同样你可能知道,匿名类间接存储对父类的引用,所以为了安全并避免奇怪的循环依赖性阻止你的片段被GCed,我建议你声明你的匿名类(TextWatcher
和Filter
)public static
类:
public static class MyTextWatcher implements TextWatcher
{
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
//you might need to pass this adapter as a constructor parameter
customAdapter.getFilter().filter(cs);
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
}
public static class MyFilter extends Filter
{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
//you implementation
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
//you implementation
}
}
然后只是实例化那些实例:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
.......
editText.addTextChangedListener(new MyTextWatcher());
.......
}
和
@Override
public Filter getFilter() {
if(filter == null)
{
filter = new MyFilter();
}
return filter;
}
另外,我发现了一些与EditText
视图相关的内存泄漏问题。您可以考虑查看this post