如何在与TextWatcher一起使用时清除EditText中的文本

时间:2013-12-27 20:04:56

标签: android

我的布局中的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();
        }
    };

1 个答案:

答案 0 :(得分:2)

首先,我要指出您的getFilter()方法非常无效。每次用户键入/删除一个字母时,它都会创建新的Filter。这对垃圾收集器来说非常紧张。相反,我建议在您的片段中创建Filter实例,并以getFilter()方法返回此实例。

另外,如果你真的想清除编辑文本并重置过滤器 - 我会在你的片段实现中覆盖onDestroyView方法并在那里做那些事情。

@Override
public void onDestroyView() {
    editText.setText("");
    editText.setOnFocusChangeListener(null);
    super.onDestroyView();
}

同样你可能知道,匿名类间接存储对父类的引用,所以为了安全并避免奇怪的循环依赖性阻止你的片段被GCed,我建议你声明你的匿名类(TextWatcherFilterpublic 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