我在我的 SherlockListFragment 中使用 SearchView 时遇到了一些麻烦。有一个自定义 ArrayAdapter 和一个列表视图,其中每个项目包含一个图像和两个 TextView。在我为我的 ListFragment 应用 SearchView 之前,一切都运行良好。搜索图标是可扩展的,我还可以在搜索栏中输入单词。
问题
自定义适配器现在能够过滤列表视图,但是当我从可扩展搜索视图中删除最后一个字母或关闭搜索视图时,应用程序崩溃了。
我在下面附加了我的 ArrayAdapter 类以及我的 SherlockListFragment。
具有过滤器类的自定义 ArrayAdapter
public static class ShopListAdapter extends ArrayAdapter<ShopEntry>
{
private final LayoutInflater mInflater;
private List<ShopEntry> filteredData;
private List<ShopEntry> originalData;
public ShopListAdapter(Context context, List<ShopEntry> filteredData)
{
super(context, android.R.layout.simple_list_item_2, filteredData);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.filteredData = filteredData;
}
public void setData(List<ShopEntry> data)
{
clear();
if(data != null)
{
for(ShopEntry ShopEntry : data)
{
add(ShopEntry);
}
}
filteredData = data;
originalData = data;
}
@Override
public int getCount()
{
return filteredData.size();
}
@Override
public ShopEntry getItem(int pos)
{
return filteredData.get(pos);
}
/**
* Populate new items in the list.
*/
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view;
if(convertView == null)
{
view = mInflater.inflate(R.layout.specific_shop_list_item,
parent, false);
}
else
{
view = convertView;
}
ShopEntry item = filteredData.get(position);
String url = item.getImg();
((SmartImageView) view.findViewById(R.id.shopImg)).setImageUrl(url);
((TextView) view.findViewById(R.id.shopType)).setText(item
.getShopName());
view.setBackgroundColor(0xff1e8e8);
return view;
}
private class MyFilter extends Filter
{
@SuppressWarnings("unchecked" )
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
{
if(results != null && results.count > 0)
{
filteredData = (ArrayList<ShopEntry>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
constraint = constraint.toString();
filteredData = originalData;
if(constraint.length() == 0 || constraint.equals(""))
{
FilterResults original = new FilterResults();
original.count = filteredData.size();
original.values = filteredData;
return original;
}
else
{
List<ShopEntry> filtered = new ArrayList<ShopEntry>();
for(ShopEntry l : filteredData)
{
if(l.getShopName().contains(constraint))
{ // YOU NEED TO CHANGE THIS
filtered.add(l);
Log.d("filter", "filter " + constraint + " "
+ l.getShopName().toString());
}
}
FilterResults newFilterResults = new FilterResults();
newFilterResults.count = filtered.size();
newFilterResults.values = filtered;
return newFilterResults;
}
}
}
MyFilter mFilter;
@Override
public Filter getFilter()
{
if(mFilter == null)
{
mFilter = new MyFilter();
}
return mFilter;
}
}
我的 ListFragment 类
public class ShopListFragment extends SherlockListFragment implements
LoaderManager.LoaderCallbacks<List<ShopEntry>>, OnQueryTextListener
{
List<ShopEntry> shopEntry = new ArrayList<ShopEntry>();
// This is the Adapter being used to display the list's data.
ShopListAdapter mAdapter;
SearchView searchView;
// If non-null, this is the current filter the user has provided.
String mCurFilter = "";
OnQueryTextListenerCompat mOnQueryTextListenerCompat;
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No Such Shop");
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new ShopListAdapter(getActivity(), shopEntry);
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
// Place an action bar item for searching.
// super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_with_search, menu);
MenuItem item = menu.findItem(R.id.action_search);
searchView = new SearchView(getSherlockActivity().getSupportActionBar()
.getThemedContext());
searchView.setQueryHint(getString(R.string.search_hint));
searchView.setOnQueryTextListener(this);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if(currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
item.setOnActionExpandListener(new OnActionExpandListener()
{
@Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
searchView.onActionViewCollapsed();
searchView.setQuery(null, true);
searchView.clearFocus();
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item)
{
// TODO Auto-generated method stub
return true;
}
});
}
else
{
// do something for phones running an SDK before froyo
searchView.setOnCloseListener(new OnCloseListener()
{
@Override
public boolean onClose()
{
searchView.onActionViewCollapsed();
searchView.setQuery(null, true);
searchView.clearFocus();
return false;
}
});
}
item.setActionView(searchView);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onQueryTextChange(String newText)
{ // called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
// Don't do anything if the filter hasn't actually changed.
// Prevents restarting the loader when restoring state.
if(mCurFilter == null && newFilter == null)
{
return true;
}
if(mCurFilter != null && mCurFilter.equals(newFilter))
{
return true;
}
mCurFilter = newFilter;
mAdapter.getFilter().filter(mCurFilter.toString());
getLoaderManager().restartLoader(0, null, this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query)
{
// TODO Auto-generated method stub
return true;
}
@Override
public Loader<List<ShopEntry>> onCreateLoader(int id, Bundle args)
{
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
return new ShopListLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<List<ShopEntry>> loader,
List<ShopEntry> data)
{
// Set the new data in the adapter.
mAdapter.setData(data);
// The list should now be shown.
if(isResumed())
{
setListShown(true);
}
else
{
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<List<ShopEntry>> loader)
{
// Clear the data in the adapter.
mAdapter.setData(null);
}
}
日志文件
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:212)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:30)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:94)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:49)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:155)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:356)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:136)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.widget.TextView.doKeyDown(TextView.java:5385)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.widget.TextView.onKeyDown(TextView.java:5204)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.widget.AutoCompleteTextView.onKeyDown(AutoCompleteTextView.java:716)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.KeyEvent.dispatch(KeyEvent.java:2609)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.View.dispatchKeyEvent(View.java:7205)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1920)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1395)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.app.Activity.dispatchKeyEvent(Activity.java:2370)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.actionbarsherlock.app.SherlockFragmentActivity.dispatchKeyEvent(SherlockFragmentActivity.java:121)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1847)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3701)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3651)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2818)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.os.Handler.dispatchMessage(Handler.java:99)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.os.Looper.loop(Looper.java:137)
08-20 01:44:44.549: E/AndroidRuntime(4246): at android.app.ActivityThread.main(ActivityThread.java:5041)
08-20 01:44:44.549: E/AndroidRuntime(4246): at java.lang.reflect.Method.invokeNative(Native Method)
08-20 01:44:44.549: E/AndroidRuntime(4246): at java.lang.reflect.Method.invoke(Method.java:511)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-20 01:44:44.549: E/AndroidRuntime(4246): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-20 01:44:44.549: E/AndroidRuntime(4246): at dalvik.system.NativeStart.main(Native Method)
谁能帮我 ?谢谢