在搜索查看SherlockListFragment [英] SearchView in SherlockListFragment
问题描述
我在我的SherlockListFragment.There使用搜索查看是一个自定义ArrayAdapter并包含一个图像和两个TextViews每个项目一个ListView一些麻烦。一切正常,直到我申请搜索查看我的ListFragment。搜索图标可扩展,我也能够进入的话在搜索栏中。
I have some troubles using SearchView in my SherlockListFragment.There is a custom ArrayAdapter and a listview which contains one image and two TextViews for each item. Everything works well until I applied SearchView for my ListFragment. The search icon is expandable and I'm also able to enter words into the search bar.
问题
自定义适配器现在能够过滤列表视图,但是当我从扩展搜索查看删除最后一个字母,或关闭搜索查看,应用程序崩溃。
The custom adapter is able to filter the listview now, but when I delete the last letter from the expandable searchview, or close the searchview, the app crashed.
我重视我的ArrayAdapter类,还有,我下面的SherlockListFragment。
I have attached my ArrayAdapter class, as well as, my SherlockListFragment below.
自定义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)
谁能帮我? THX
Can anyone help me ? thx
推荐答案
在搜索查看
夏洛克扩大它集的TextView
组件,
,可以从源头上看到:
When the SearchView
in Sherlock is expanded it sets the TextView
component to ""
, you can see it from the source:
@Override
public void onActionViewExpanded() {
if (mExpandedInActionView) return;
mExpandedInActionView = true;
mCollapsedImeOptions = mQueryTextView.getImeOptions();
mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
mQueryTextView.setText("");
setIconified(false);
}
这就是为什么你的过滤器返回原始数据。相反,相比于 android.widget.SearchView
它不设置查询时动作视图也崩溃了。你需要省略为(除非需要)过滤,并检查如果你是无效的的ListView长话短说
进行过滤的时候,因为你还没有张贴的过滤实现。
That's why your filter returns the original data. Contrary, comparing to the android.widget.SearchView
it does not set the query to "" when the action view is also collapsed. Long story short you need to omit filtering with "" (unless needed), and also check if you are invalidating the ListView
when the filtering is performed, since you havent posted the filtering implementation.
编辑:过滤列表视图的示例
Example of filtering listview
私有类MyFilter扩展过滤器{
private class MyFilter extends Filter {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results!=null && results.count > 0) {
items = (ArrayList<Data>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
items = mOriginalData;
if (constraint.length() == 0 || constraint.equals("")) {
FilterResults original = new FilterResults();
original.count = items.size();
original.values = items;
return original;
} else {
List<Data> filtered = new ArrayList<Data>();
for (Data l : items) {
if ( SOME CONDITION TO FILTER ){ // YOU NEED TO CHANGE THIS
filtered.add(l);
}
}
FilterResults newFilterResults = new FilterResults();
newFilterResults.count = filtered.size();
newFilterResults.values = filtered;
return newFilterResults;
}
}
};
在您的适配器:
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new MyFilter();
}
return mFilter;
}
这篇关于在搜索查看SherlockListFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!